- Home /
GUI position and size in different screen resolutions
Hi, I know this question has been done before to an extent, but after finding what I believed to be a solution to the problem, I still have a problem. I have made changes to my script to reposition and resize GUIs to accommodate the screen resolution being used, as certain things are in the wrong place in resolutions other than the one I used for testing (1366x768). My game features meters for the player's powers, displaying how much power the player has with blocks. The windows containing the blocks were fixed with the script change and now move and change size for different resolutions. However, a problem still remains with the blocks. I felt the easiest way to demonstrate this was with screenshots, one in 1366x768 and one in 1024x768 (I haven't made changes to the yellow and red blocks in the images). I will also give the relevant sections of script:
void Start()
{
resolution = new Vector2(Screen.width, Screen.height);
x = Screen.width/1366.0f;
y = Screen.height/768.0f;
}
void Update()
{
if(Screen.width!=resolution.x || Screen.height!=resolution.y)
{
resolution = new Vector2(Screen.width, Screen.height);
x =resolution.x / 1366.0f;
y =resolution.y / 768.0f;
}
}
void OnGUI()
{
GUI.skin = interfaceskin2;
GUI.Box(new Rect(145*x, 650*y, 270*x, 100*y), "");
GUI.Box(new Rect(415*x, 650*y, 270*x, 100*y), "");
GUI.Box(new Rect(685*x, 650*y, 270*x, 100*y), "");
GUI.Box(new Rect(955*x, 650*y, 270*x, 100*y), "");
GUI.Label(new Rect(250*x, 660*y, 50, 25), " Jump");
if(PlayerPrefs.HasKey("ShieldLevel"))
{
GUI.Label(new Rect(520*x, 660*y, 50, 25), " Shield");
}
if(PlayerPrefs.HasKey("BoostLevel"))
{
GUI.Label(new Rect(790*x, 660*y, 50, 25), " Boost");
}
if(PlayerPrefs.HasKey("PulseLevel"))
{
GUI.Label(new Rect(1060*x, 660*y, 50, 25), " Pulse");
}
if(jumppower > 0f)
{
GUI.Label(new Rect(190*x, 690*y, 31.25f*x, 31.25f*y), BlueBar);
}
if(jumppower > 10f)
{
GUI.Label(new Rect(220*x, 690*y, 31.25f*x, 31.25f*y), BlueBar);
}
if(jumppower > 20f)
{
GUI.Label(new Rect(250*x, 690*y, 31.25f*x, 31.25f*y), BlueBar);
}
if(jumppower > 30f)
{
GUI.Label(new Rect(280*x, 690*y, 31.25f*x, 31.25f*y), BlueBar);
}
if(jumppower > 40f)
{
GUI.Label(new Rect(310*x, 690*y, 31.25f*x, 31.25f*y), BlueBar);
}
if(jumppower > 50f)
{
GUI.Label(new Rect(340*x, 690*y, 31.25f*x, 31.25f*y), BlueBar);
}
if(PlayerPrefs.HasKey("ShieldLevel"))
{
if(shieldpower > 0f)
{
GUI.Label(new Rect(460*x, 690*y, 31.25f*x, 31.25f*y), GreenBar);
}
if(shieldpower > 10f)
{
GUI.Label(new Rect(490*x, 690*y, 31.25f*x, 31.25f*y), GreenBar);
}
if(shieldpower > 20f)
{
GUI.Label(new Rect(520*x, 690*y, 31.25f*x, 31.25f*y), GreenBar);
}
if(shieldpower > 30f)
{
GUI.Label(new Rect(550*x, 690*y, 31.25f*x, 31.25f*y), GreenBar);
}
if(shieldpower > 40f)
{
GUI.Label(new Rect(580*x, 690*y, 25, 25), GreenBar);
}
if(shieldpower > 50f)
{
GUI.Label(new Rect(610*x, 690*y, 25, 25), GreenBar);
}
}
}
Screenshots (1366x768 first, then 1024x768):
I just thought I should clarify that I'm looking for a solution to the blocks being squashed together, as I thought that they would be positioned and sized to look the same in all resolutions.
Answer by VincentDB · Sep 15, 2014 at 08:02 PM
A solution is to set all position to a scale from device size. For example, instead of set a position to 1366/2, set it to Screen.width / 2
If your good at math (basics), you can easily make something work in all resolutions.
Your code should start by:
void OnGUI()
{
GUI.skin = interfaceskin2;
//spacing is the space in pixels on left and right
float spacing = (Screen.width - (4 * 270)) / 2;
GUI.Box(new Rect(spacing, Screen.height - 100 - 20, 270, 100), ""); //20 pixel from bot in this exemple
GUI.Box(new Rect(spacing + 270, Screen.height - 100 - 20, 270, 100), "");
GUI.Box(new Rect(spacing + (270 * 2), Screen.height - 100 - 20, 270, 100), "");
GUI.Box(new Rect(spacing + (270 * 3), Screen.height - 100 - 20, 270, 100), "");
//TODO ...
}
I've heard that Screen.width and Screen.height aren't that reliable for keeping consistency on multiple resolutions. Though, if you think it would work, could you suggest how I'd use it to fix the problem with the blocks (the labels with bluebar/greenbar textures)?
I actually found another solution. One thing I needed to do was change the gui labels with the 2D textures to gui drawtextures. It occurred to me that the unity preview resolution is not actually the resolution that it claims to be (1366x768 is actually 1062x597). With couple of tweaks in the numbers, I then found I could solve the issue as in this example: GUI.DrawTexture(new Rect(355f/1062f *Screen.width, 537.5f/597f *Screen.height, 20f/1062f *Screen.width, 19f/597f *Screen.height), GreenBar);
So the position and size are divided by the testing resolution in which they are all in the right place and the right size, then multiplied by the resolution the game is played in to fit the different resolution.