Search Unity

GUI - Text/Font size and adjusting it for Screen size/Resolution

Discussion in 'Scripting' started by Ovredon, Jul 23, 2013.

  1. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    Hello,

    So at the moment I was just setting up some GUI interfaces for the player however after finally getting over the hurdle of scaling / screen size and textures, I've come across "TEXT".

    Basically I want to be able to adjust the text size of the GUIStyle I'm using for all the GUI elements according to the current size of the screen, I have figured out a way of doing it for native/proper resolutions such as 1920x1080 or 1024x768, however the problem I think I'll have is if the player wants a custom resolution or one that I don't think of.

    What I need is an automatic calculation which does what I'm doing as soon as the screen sizes has changed.

    Code (csharp):
    1.  
    2.  
    3.         if(Screen.height >= 900  Screen.width >= 1500)
    4.         {
    5.             //GUI.matrix = Matrix4x4.TRS( Vector3.zero, Quaternion.identity, new Vector3( Screen.width / 1920.0f, Screen.height / 1080.0f, 1.0f ) );   
    6.             TextStyle.fontSize = 18;
    7.         }
    8.         else if(Screen.height <= 800  Screen.width <= 1200)
    9.         {
    10.             //GUI.matrix = Matrix4x4.TRS( Vector3.zero, Quaternion.identity, new Vector3( Screen.width / 1024.0f, Screen.height / 768.0f, 1.0f ) );
    11.             TextStyle.fontSize = 10;
    12.         }
    13.  
    14.  
     
  2. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    The only solution I can think of is that I could just aswell as having all the native resolutions have a few in between each resolution to adjust the text like the example above - however its kind of sloppy, and I still need a way of doing it without putting it in the update function.

    Textures do it automatically I just can't apply the same method for text.

    Any help would be greatly appreciated.
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The idea is that you set up a "virtual" resolution and code everything to that, and use GUI.matrix to scale. You don't need to hard-code anything.

    Code (csharp):
    1. var virtualWidth = 1920.0;
    2. var virtualHeight = 1080.0;
    3.  
    4. function Start () {
    5.     matrix = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, Vector3(Screen.width/virtualWidth, Screen.height/virtualHeight, 1.0));
    6. }
    7.  
    8. function OnGUI () {
    9.     GUI.matrix = matrix;
    10.     GUILayout.Label ("Woo");
    11. }
    So here you assume the resolution is 1920x1080, and it's scaled to whatever the real screen res is.

    --Eric
     
  4. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    Okay, Its just that cause I was testing and going from a small preview window to a massive one it was screwing up my resolution. The hard-coded stuff you saw there was my attempt of previewing what I want it to look like when the text is scaled properly to different resolutions.

    So lets say that a user plays on a laptop that only has 720p resolution.

    when the game is set to 720p either automatically or more likely by the user setting that resolution in the options menu, the options menu would communicate with the variable "virtualHeight" and "virtualWidth" to change the virtual canvas and allow all the ui elements to fit properly just like how I was trying to do in my example??
     
  5. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    Also can you make that example into C# please? :)
     
  6. Sahkan

    Sahkan

    Joined:
    Mar 3, 2013
    Posts:
    204
    I'm not sure if i didn't miss something converting from UnityScript to C# but give it a try :
    Code (csharp):
    1. float virtualWidth = 1920.0f;
    2. float virtualHeight = 1080.0f;
    3. void Start () {
    4.     matrix = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, Vector3(Screen.width/virtualWidth, Screen.height/virtualHeight, 1.0f));
    5. }
    6. void OnGUI ()
    7. {
    8.     GUI.matrix = matrix;
    9.     GUILayout.Label ("Woo");
    10. }
     
  7. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    Thanks Sahkan :D

    hmm. well, atm changing the matrix isn't' doing anything for me
     
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No. There are no options, it just scales based on the screen resolution. You do nothing, except code your GUI using the virtualWidth and virtualHeight variables. (Which actually probably shouldn't be public; make them constants instead.)

    --Eric
     
  9. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    But what if someone can't play the game at 1920x1080 and needs to use a lower resolution, what then?
     
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Then they just user a lower resolution, and the GUI scales down. I think you're way overthinking this....

    --Eric
     
  11. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    Maybe. But when I have a smaller window that 1920x1080 and the matrix has that value set in it, the GUI just squishes and distorts. So I don't know what I'm doing wrong here :(
     
  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Actually, that doesn't account for different aspect ratios. Fortunately there aren't too many, so you can set up different virtual resolutions for 16:9, 16:10, 3:2 and 4:3, and that should cover pretty much everything.

    --Eric
     
  13. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    Okay thanks for all your help Eric. Last question I think..

    if I used 1920x1080 for my 16:9 aspect ratio, would the GUI scale down without distorting and cutting off anything?

    Likewise for 4:3 (1280x960)

    so long as the scale down was in the same aspect ratio.
     
  14. XGundam05

    XGundam05

    Joined:
    Mar 29, 2012
    Posts:
    473
    It shouldn't distort/cut off anything if it's the same aspect ratio.

    For that matter, you can enforce a specific aspect ratio and then letterbox or pillarbox it depending on the screen. A lot of console-to-pc ports do this.
     
  15. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    I might have to do that sadly.

    I might make it for 16:9 and then if someone needs to 4:3 it it'll have to have black bars. :\
     
  16. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    originally I've been doing Rect EnergyBar = new Rect (Screen.width * 0.03f,Screen.height * 0.04f,(Screen.width * 0.002f) * GUIPlayerEnergy,Screen.height * 0.015f);

    but it was giving distortion and scaling problems.

    However now if I use the GUI matrix thing with a set aspect ratio I can just use whole numbers there.
     
  17. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Nothing would ever be cut off, but if you used 1920x1080 as the virtual resolution, then the GUI would be squished on 4:3 screens. That's why I suggested using several different virtual resolutions to account for different aspect ratios. It is of course more work, but not anywhere near as much work as trying to code for every possible screen resolution.

    --Eric
     
  18. Ovredon

    Ovredon

    Joined:
    Jul 13, 2013
    Posts:
    161
    Yeah I agree Eric. Thanks everyone for helping me to use and implement this matrix method.


    I got it working properly now with 16:9 ratio.

    For the benefit of myself and anyone who comes here, if I use a position like this : Rect AmmoBar = new Rect (1780,5,80,80);

    That means that if I were to have a separate aspect ratio setting like 4:3, I couldn't use the above and I would need to have some sort of argument which finds out what aspect ratio it is and then use a different version of the above.... For example:

    16:9
    Rect AmmoBar = new Rect (1780,5,80,80);

    4:3
    Rect AmmoBar = new Rect (960,5,80,80);


    Is all of the above correct, can someone confirm?

    or am I overthinking it again?
     
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Seems right.

    --Eric
     
  20. barbe63

    barbe63

    Joined:
    Oct 6, 2014
    Posts:
    35
    I didn't managed to use matrix properly but this simple code just got me the result i expected so i share:
    Code (CSharp):
    1. guiStyle.fontSize=  Mathf.Min(Mathf.FloorToInt(Screen.width * fontSize/1000), Mathf.FloorToInt(Screen.height * fontSize/1000));
    Then all you have to do is to set the int fontSize to a value that suits you.
     
    Last edited: Nov 23, 2014
    unitynewbie987 likes this.
  21. Athos-Krul

    Athos-Krul

    Joined:
    Aug 12, 2014
    Posts:
    24
  22. CommunityUS

    CommunityUS

    Joined:
    Sep 2, 2011
    Posts:
    240
    I know this is a year old, but I hate leaving questions unanswered (for the next guy/gal)

    Those are variables.

    C#
    GUIStyle guiStyle;
    int fontSize;
     
  23. mrlod94

    mrlod94

    Joined:
    Jul 17, 2016
    Posts:
    2
    you should add "new" forward Vector3(Screen.width/virtualWidth, Screen.height/virtualHeight, 1.0f));
     
  24. unitynewbie987

    unitynewbie987

    Joined:
    Apr 14, 2017
    Posts:
    1
    Thanks unitynewbie987. It's working for my situtation.
     
  25. KeinZantezuken

    KeinZantezuken

    Joined:
    Mar 28, 2017
    Posts:
    53
    I'm gonna bump this thread because reasons.

    I use matrix recalculation to scale when resolution is not native intended:

    Code (CSharp):
    1. private void setMatrix()
    2.     {
    3.         float num = 1920f;
    4.         float num2 = 1080f;
    5.         this.scale.x = (float)Screen.width / num;
    6.         this.scale.y = (float)Screen.height / num2;
    7.         this.scale.z = 1f;
    8.         Matrix4x4 matrix = GUI.matrix;
    9.         this.newMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, this.scale);
    10.     }
    11.  
    My problem is that at least one specific part of GUI uses Screen.height and I can't get rid of it since it is a part of position calculation by Y/height with Camera.main.WorldToScreenPoint

    Any ideas how to handle this situation?