- Home /
Scaling GUI buttons to be the right size no mobile
What is the right way to scale GUI buttons to be the right size on different mobile screen sizes and densities?
When I create GUI that needs to be completely scalable, I don't take the classic 2D approach. It's possible to write stuff in OnGUI which completely scales based on the screen size, but I prefer a 3D approach.
This means my GUI-system is setup in 3D, with planes and colliders. That way my buttons are actually rendered, and I don't have to worry about stretching on different screens.
It's also pretty easy to dock elements to certain screen positions (top left corner, etc.) with some raycasting code.
It really depends on what you need, but if you consider taking this 3D approach, I'm happy to answer further questions you have.
Greets
Answer by robhuhn · Oct 25, 2012 at 07:43 AM
I know two approaches to scale the gui resolution independently.
One way is using GUI.matrix and multiply it with Matrix4x4.Scale(new Vector3(factor, factor, factor)). That will everything scale up or down including fonts. When I needed a gui scaling, that method didn't fit my needs so I calculated it on my own and built an android-like scale system.
In c# I wrote extension methods to convert the values (simplified code). I wrote a lot of them for int, float, rect, vectors, GuiStyle,... E.g.
@Edit: class added
public static class DisplayMetricsUtil
{
public enum ResolutionType
{
ldpi,
mdpi,
hdpi,
xhdpi
}
private const float DEFAULT_DPI = 160.0f;
private static bool isScreenSizeInitialized = false;
private static Rect ScreenSize;
public static Vector2 DpToPixel(this Vector2 vector)
{
return new Vector2(vector.x.DpToPixel(), vector.y.DpToPixel());
}
public static Vector3 DpToPixel(this Vector3 vector)
{
return new Vector3(vector.x.DpToPixel(), vector.y.DpToPixel(), vector.z.DpToPixel());
}
public static Rect DpToPixel(this Rect rect)
{
return new Rect(rect.x.DpToPixel(), rect.y.DpToPixel(), rect.width.DpToPixel(), rect.height.DpToPixel());
}
public static int DpToPixel(this int dp)
{
// Convert the dps to pixels
return (int) (dp * GetScale() + 0.5f);
}
public static int DpToPixel(this float dp)
{
// Convert the dps to pixels
return (int) (dp * GetScale() + 0.5f);
}
public static int PixelToDp(this int px)
{
// Convert the pxs to dps
return (int) (px / GetScale() - 0.5f);
}
public static int PixelToDp(this float px)
{
// Convert the pxs to dps
return (int) (px / GetScale() - 0.5f);
}
public static GUIStyle DpToPixel(this GUIStyle style)
{
GUIStyle stylePx = new GUIStyle(style);
stylePx.border = stylePx.border.DpToPixel();
stylePx.padding = stylePx.padding.DpToPixel();
stylePx.margin = stylePx.margin.DpToPixel();
stylePx.overflow = stylePx.overflow.DpToPixel();
stylePx.contentOffset = stylePx.contentOffset.DpToPixel();
stylePx.fixedWidth = stylePx.fixedWidth.DpToPixel();
stylePx.fixedHeight = stylePx.fixedHeight.DpToPixel();
stylePx.fontSize = stylePx.fontSize.DpToPixel();
return stylePx;
}
public static RectOffset DpToPixel(this RectOffset rectOffset)
{
return new RectOffset(
rectOffset.left.DpToPixel(),
rectOffset.right.DpToPixel(),
rectOffset.top.DpToPixel(),
rectOffset.bottom.DpToPixel());
}
public static Rect ScreenSizeDpUnit()
{
if(!isScreenSizeInitialized)
{
ScreenSize = new Rect(0, 0, Screen.width.PixelToDp(), Screen.height.PixelToDp());
isScreenSizeInitialized = true;
}
return ScreenSize;
}
//e.g. switch fonts to have the correct fontsize.
public static ResolutionType GetResolutionType()
{
float scale = GetDPI() / DEFAULT_DPI;
ResolutionType res;
//http://developer.android.com/guide/practices/screens_support.html
if(scale > 1.5f)
{
res = DisplayMetricsUtil.ResolutionType.xhdpi;
}
else if(scale > 1f)
{
res = DisplayMetricsUtil.ResolutionType.hdpi;
}
else if(scale > 0.75f)
{
res = DisplayMetricsUtil.ResolutionType.mdpi;
}
else
{
res = DisplayMetricsUtil.ResolutionType.ldpi;
}
return res;
}
private static float GetDPI()
{
return Screen.dpi == 0 ? DEFAULT_DPI : Screen.dpi;
}
private static float GetScale()
{
return GetDPI() / DEFAULT_DPI;
}
}
Any chance that you would share more source code? I like your solution, but it's hard to figure out what to do with the few functions you outlined.
how do we use extension methods in unity? Where should I copy this codescript?
Your answer
Follow this Question
Related Questions
Can I use GUI.DrawTexture/Graphics.DrawTexture with UGUI? 0 Answers
Hold Down GUIButton? 1 Answer
Free Gui solutions 2 Answers
Unity 4.7 - OnGUI prevent click/touch through 0 Answers
OnGUI button created by a foreach loop 4 Answers