I develop for android, and I’m going to assume IOS would act the same way, and with my experience gui.matrix is horrible.
Now I know it’s how we are using it because many other people are able to get it to work but I was having the same issue as you. As I result I do exactly as you are doing in your second example.
All my gui components are displayed using coordinates that are a percentage of my screen size.
There are 2 things you can do to make it no different then just specifying “5,6,8,1” in your rectangle:
Make a variable that has Screen.Width and Screen.Height. Define these values in the Awake or Start method sense they don’t change. Beyond that do the same thing for all your rectangles. That way you calculate it once and then just grab the values rather then executing them every GUI frame. Heres a snip-it from my UI script:
//initializing all the boxes
private void InitializeRects(){
box1 = new Rect(5f,(topPanelRect.height - topPanelRect.height/20f),topPanelRect.width/9f,topPanelRect.width/9f);
box2 = new Rect(screenWidth/4 - (screenWidth/4)/2,screenHeight/3, screenWidth/2 + screenWidth/4,screenHeight/2);
box3 = new Rect(screenWidth/2 + screenWidth/22,screenHeight/2 + screenHeight/6, screenWidth/5,screenHeight/7);
box4 = new Rect(screenWidth/4,screenHeight/2 + screenHeight/6, screenWidth/5,screenHeight/7);
box5 = new Rect(screenWidth/4,screenHeight/4, screenWidth/2,screenHeight/2);
box6 = new Rect(screenWidth/2 - (screenWidth/5)/2, screenHeight/2 + screenHeight/16, screenWidth/5,screenHeight/7);
box7 = new Rect(0, 0, topPanelRect.width, topPanelRect.height);
box8 = new Rect(((topPanelRect.width-(topPanelRect.height/2f + topPanelRect.height/6f))-3f), 2f, topPanelRect.height/2f + topPanelRect.height/6f, topPanelRect.height/2f + topPanelRect.height/6f);
box9 = new Rect(0, 0, bottomPanelRect.width, bottomPanelRect.height);
box10 = new Rect(3, bottomPanelRect.height/11, 250f, 50f);
box11 = new Rect((screenWidth/2)-screenWidth/4,bottomPanelRect.height/11,250f,50f);
box12 = new Rect((screenWidth/2)+screenWidth/20,bottomPanelRect.height/11,250f,50f);
box13 = new Rect(screenWidth/3 - (screenWidth/15)/2, screenHeight/15, screenWidth/3 + screenWidth/15, screenHeight/2+screenHeight/5);
box14 = new Rect(screenWidth/3 + screenWidth/23, screenHeight/5 + screenHeight/13, screenWidth/4, screenHeight/12);
box15 = new Rect(screenWidth/3 + screenWidth/23, screenHeight/3 + screenHeight/16, screenWidth/4, screenHeight/12);
box16 = new Rect(screenWidth/3 + screenWidth/23, screenHeight/2 + screenHeight/80, screenWidth/4, screenHeight/12);
box17 = new Rect(screenWidth/3 + screenWidth/23, screenHeight/2 + screenHeight/8, screenWidth/4, screenHeight/12);
box18 = new Rect(screenWidth/3 - (screenWidth/15)/2, screenHeight/3 - (screenHeight/7)/2, screenWidth/3 + screenWidth/15, screenHeight/3 + screenHeight/5);
box19 = new Rect(screenWidth/3 + screenWidth/23, screenHeight/3 + screenHeight/7, screenWidth/4, screenHeight/12);
box20 = new Rect(screenWidth/3 + screenWidth/23, screenHeight/3 + screenHeight/4, screenWidth/4, screenHeight/12);
box21 = new Rect(screenWidth/3 + screenWidth/23, screenHeight/3 + screenHeight/3 + screenHeight/50, screenWidth/4, screenHeight/12);
box22 = new Rect(0, bottomPanelRect.height/3, Screen.width-5, Screen.height+12);
box23 = new Rect(screenWidth - (screenWidth/3) - (screenWidth/9),topPanelRect.height+screenHeight/10, screenWidth/3 + screenWidth/10, screenHeight/2);
box24 = new Rect(screenHeight/50, screenHeight/50, screenWidth/3 + screenWidth/10, box23.height/4);
box25 = new Rect(screenHeight/50, screenHeight/14, screenWidth/3 + screenWidth/10, box23.height/4);
box26 = new Rect(screenHeight/50, screenHeight/7, screenWidth/3 + screenWidth/10, box23.height);
box27 = new Rect(screenWidth/4 - screenWidth/20, screenHeight/15, screenWidth/2 + screenWidth/10, screenHeight/2+screenHeight/3+screenHeight/10);
int yLoxationA1 = screenHeight/4;
int yLocationB1 = yLoxationA1 + screenHeight/20;
int yLocationA2 = screenHeight/2 - screenHeight/9;
int yLocationB2 = yLocationA2 + screenHeight/20;
int yLocationB3 = yLocationB2 + screenHeight/9;
int yLocationA4 = yLocationB3 + screenHeight/10;
int yLocationA5 = yLocationA4 + screenHeight/10;
int yLocationA7 = yLocationA5 + screenHeight/10;
int yLocationA6 = yLocationA7 + screenHeight/50;
box28 = new Rect(screenWidth/3, yLoxationA1, screenWidth/4,screenHeight/20);
box29 = new Rect(screenWidth/3 + screenWidth/25, yLocationB1, screenWidth/7, screenHeight/15);
box30 = new Rect(screenWidth/3, yLocationA2, screenWidth/4,screenHeight/20);
box31 = new Rect(screenWidth/3 + screenWidth/25, yLocationB2, screenWidth/7, screenHeight/15);
box32 = new Rect(screenWidth/2 + screenWidth/20, yLocationB1, screenWidth/10, screenHeight/11);
box33 = new Rect(screenWidth/2 + screenWidth/20, yLocationB2, screenWidth/10, screenHeight/11);
box34 = new Rect(screenWidth/4, yLocationB3, screenWidth/10, screenHeight/11);
box35 = new Rect(screenWidth/4, yLocationA4, screenWidth/10, screenHeight/11);
box36 = new Rect(screenWidth/4, yLocationA5, screenWidth/10, screenHeight/11);
box39 = new Rect(screenWidth/2 + screenWidth/35, yLocationB3, screenWidth/10, screenHeight/11);
box42 = new Rect(screenWidth/2 + screenWidth/35, yLocationA4, screenWidth/10, screenHeight/11);
box37 = new Rect(screenWidth/2 - (screenWidth/6)/2,yLocationA6,screenWidth/6,screenHeight/10);
buildMenuAllTowersFixedWidth = screenWidth/13;
buildMenuAllTowersFixedHeight = buildMenuAllTowersFixedWidth;
buildMenuAllTowersFixedY = Screen.height-buildMenuAllTowersFixedHeight-6-(int)bottomPanelRect.height;
buildMenuAllTowersFixedTotalBoxWidth = buildMenuAllTowersFixedWidth + 6;
towerList=BuildManager.GetTowerList();
for(int i=1; i<towerList.Length; i++){
buildMenuAllTowersFixedTotalBoxWidth += (buildMenuAllTowersFixedWidth + 3);
}
box38 = new Rect(0,buildMenuAllTowersFixedY,buildMenuAllTowersFixedTotalBoxWidth,buildMenuAllTowersFixedWidth+10);
box40 = new Rect(screenWidth/20,buildMenuAllTowersFixedY - screenHeight/6,screenWidth/8,screenHeight/8);
box41 = new Rect(screenWidth/5,buildMenuAllTowersFixedY - screenHeight/6,screenWidth/8,screenHeight/8);
}
And in my Start method I call InitializeRects();
And a part of my GUI looks like:
//this is the option menu from when you click the "options" button from inside the pause menu
void ShowTheOptionsMenu(){
//draw the box for the options menu
GUI.skin.box.normal.background = mapBackgroundBox;
GUI.Box(box27, "
Options");
//change the font to the smaller font for small screens
if(useSmallText){
GUI.skin.font=infoFont;
}
//sound effects volume
GUI.Label(box28,"Sound Effects Volume");
soundEffectsVolume = GUI.HorizontalSlider(box29, soundEffectsVolume, 0.0f, 1.0f);
//Music volume
GUI.Label(box30,"Music Volume");
musicVolume = GUI.HorizontalSlider(box31, musicVolume, 0.0f, 1.0f);
//change the font back to default font so it doesn't mess up the rest of the screen
if(useSmallText){
GUI.skin.font=defaultFont;
}
//sound effects on/off
soundEffectsMutedConvertBooltoInt = GUI.Toggle(box32, soundEffectsMutedConvertBooltoInt, "Mute");
//music on/off
musicVolumeConvertBoolToIn = GUI.Toggle(box33, musicVolumeConvertBoolToIn, "Mute");
//High detail on or off
showHighDetailConvertIntToBool = GUI.Toggle(box34, showHighDetailConvertIntToBool, "High Detail");
//Vibration on or off
playVibrationsConvertedIntToBool = GUI.Toggle(box35, playVibrationsConvertedIntToBool, "Play Vibrations");
//FPS on or off
showTheFPSConvertIntToBool = GUI.Toggle(box36, showTheFPSConvertIntToBool, "Show your FPS");
//ourTerrain on or off
showTheTerrainConvertIntToBool = GUI.Toggle(box39, showTheTerrainConvertIntToBool, "Show Terrain");
//auto save on or off
autoSaveOnConvertIntToBool = GUI.Toggle(box42, autoSaveOnConvertIntToBool, "Allow Autosave");
if(GUI.Button(box37, "Save")){
SaveThePlayerPrefs();
SetThePlayerPrefs();
showingOptions = false;
}
SaveThePlayerPrefs();
SetThePlayerPrefs();
}
Now this might not be the BEST way, or the prettiest, but it works. And it works pretty nicely. I have 4 different devices I test on, all of them are different dpi and screen resolutions - and my gui is pretty much identical on all of them.