Unity: Scaling the GUI based on the screen resolution
Posted by DimasTheDriver | Filed under Featured, Programming
![Unity: Scaling the GUI based on the screen resolution Unity: Scaling the GUI based on the screen resolution thumbnail](https://i-blog.csdnimg.cn/blog_migrate/a0b685bd40b6dd347667e501a38b2998.png)
As hinted by other posts, here, you will find how to properly scale the GUI elements based on screen resolution. As one may have noticed, Unity doesn’t scale the GUI elements based on the screen resolution, requiring a script to do the job, which is explained in this post. I will assume that the reader already knows how to create and render GUI elements in Unity using the MonoBehaviour’s OnGUI() function and GUISkin objects.
The best way to explain how to properly scale a GUI element is through an example. That said, for this post, let’s assume that we wanted a yellow rectangle to be rendered at the top left and bottom right corners of the screen, like this:
![Yellow squares at the edges of the screen. Yellow squares.](https://i-blog.csdnimg.cn/blog_migrate/2138072c8e3906feb6ca03548969fd22.png)
Yellow rectangles at the edges of the screen.
The first thing to have in mind when creating a GUI for multiple resolutions is that there are no absolute pixel values, only relative ones. This means that all GUI elements must be positioned at a certain distance from one (or more) screen edge(s). Since it’s not possible to create relative positions in a graphical editing software, there is the need to define a target distance from the screen edges when it has a specific resolution . In this example, we will define that the two GUI elements must have a distance of 20 pixels from the screen’s edges when the resolution is 1920×1080. This could have been any other distance for any other resolution, it’s just a place to start.
![Yellow square position measurements.](https://i-blog.csdnimg.cn/blog_migrate/604f1367063c9e3191602c6b4c86bbf3.png)
The image must be 20px from the edges. The width and height of the GUI element are going to play an important role in the script.
Finally, here’s the code that properly scales and positions the GUI based on the screen resolution:
using UnityEngine;
using System.Collections;
public class GUIScaleExample : MonoBehaviour
{
//a GUISkin object to draw the GUI image
public GUISkin guiSkin;
//the GUI scale ratio
private float guiRatio;
//the screen width
private float sWidth;
//create a scale Vector3 with the above ratio
private Vector3 GUIsF;
//At this script initialization
void Awake()
{
//get the screen's width
sWidth = Screen.width;
//calculate the scale ratio
guiRatio = sWidth/1920;
//create a scale Vector3 with the above ratio
GUIsF = new Vector3(guiRatio,guiRatio,1);
}
//Draws GUI elements
void OnGUI()
{
//scale and position the GUI element to draw it at the screen's top left corner
GUI.matrix = Matrix4x4.TRS(new Vector3(GUIsF.x,GUIsF.y,0),Quaternion.identity,GUIsF);
//draw GUI on the top left
GUI.Label(new Rect(20,20,258,89),"",guiSkin.customStyles[0]);
//scale and position the GUI element to draw it at the screen's bottom right corner
GUI.matrix = Matrix4x4.TRS(new Vector3(Screen.width - 258*GUIsF.x,Screen.height - 89*GUIsF.y,0),Quaternion.identity,GUIsF);
//draw GUI on the bottom right
GUI.Label(new Rect(-20,-20,258,89),"",guiSkin.customStyles[0]);
}
}
Right at the beginning of the code, a GUISkin object is declared at line 7, to render the yellow square as a GUI element. Thefloat guiRatio variable is where the ratio between the screen’s width and the expected width is stored (line 10). The variablesWidth at line 13 stores the screen’s width. The GUIsFvector will be created using the above ratio, and later on, it’s going to be used to properly scale the GUI elements (line 16).
Inside the Awake() method, all these declared variables are initialized. Line 24 is definitively the most important one. It divides the screen width by the assumed width (in our case1920) and stores it at the guiRatio variable. After that, theGUIsF scale vector is created. Again, 1920 is just a value that was determined as an example, it could have been set as any other. Alternatively, the height of the screen could be divided by 1080 if that made more sense, as a result, all GUI elements would have been scaled according to the screen’s height.
Moving on to the OnGUI() method, a“GUI.matrix = Matrix4x4.TRS “ line can be seen before each of the draw calls. These lines scale and position the wholeGUI system, changing it’s origin and scale by replacing it with a custom4×4 matrix. The Matrix4x4.TRS creates a Transform,Rotate and Translate 4×4 matrix, taking a Vector3, a Quaternion and another Vector3 as parameters.
The first time the GUI’s 4×4 Matrix is redefined (line 33), the GUI system origin is placed at(GUIsF.x,GUIsF.y,0), without any rotation (Quaternion.identity) and the elements below this line are scaled byGUIsF – a Vector3 composed by(guiRatio,guiRatio,1). Then, the GUI element is drawn in line 35 using this new matrix as origin, placing it near the top left corner of the screen.
For anything that is placed near the bottom and/or right edges of the screen, there’s an additional calculation that needs to be done to correctly modify the GUI system matrix. This calculation takes in consideration the width and height of the screen, so as the GUI element’s width and height. Line 38 is a good example. The origin is first translated to the bottom right of the screen and then, it’s is brought upwards and left just enough to draw the rescaled GUI element. Right after this compensation, line 40 draws the element, -20 pixels away from the origin.
The code described above scales the GUI elements and their distances from the screen edge. Therefore, the distance from the screen’s edge will be only 20px when the screen is at 1920x1080px. Smaller resolutions will result in smaller distances. Below, some screenshots of this script in action:
![Some examples. Examples screenshot.](https://i-blog.csdnimg.cn/blog_migrate/c8398bd0fc66b19b7921c3f1ee848c89.png)
The same script repositioning and resizing the GUI elements at a 4:3 and a 16:9 screen.
Here’s a Unity project with everything explained above, both inJavaScript andC#: