Search Unity

Get Aspect Ratio

Discussion in 'Scripting' started by SteveJ, Nov 15, 2013.

  1. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,085
    Hey all,

    Is there a really reliable way of getting the current aspect ratio of the player's resolution? I want to end up in this sort of situation:

    Code (csharp):
    1.  
    2. switch (GetAspectRatio())
    3. {
    4.     case "4:3":
    5.     ...
    6.     case "3:2":
    7.     ...
    8.     case "16:9":
    9.     ...
    10. }
    11.  
    I've tried a few generic C# snippets from around the web, and just some simple math attempts, but none of them seem to work reliably within the Unity Editor. Or is my problem maybe that when using Unity's drop-down list in the "Game" panel (to select 3:2, 16:9, etc), you're not getting a "true" result and that throws off calculations?
     
    hopetolive likes this.
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    For 4.3, for example, divide Screen.width/Screen.height, and if the result is somewhat close to 1.33333, then it's 4:3.

    --Eric
     
  3. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
  4. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,085
    Ok. I hadn't come across Camera.aspect - that at least simplifies one part. I guess I'll stick with this for iOS:

    Code (csharp):
    1.  
    2. if (Camera.main.aspect >= 1.7)
    3.     Debug.Log("16:9");
    4. else if (Camera.main.aspect >= 1.5)
    5.     Debug.Log("3:2");
    6. else
    7.     Debug.Log("4:3");
    8.  
    It just feels kind of "cheap" or something.
     
    Last edited: Nov 27, 2017
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It's fine.

    --Eric
     
  6. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,085
    I trust you Eric. If it's good enough for you, it's good enough for me :)
     
    hopetolive and PNUMIA-Rob like this.
  7. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    All of 'game dev' is faking it
     
  8. LukaKotar

    LukaKotar

    Joined:
    Sep 25, 2011
    Posts:
    394
    I know I'm reviving an old thread, but if it helps, I just posted a script to the Unity Wiki, which allows you to get an aspect ratio as Vector2. I hope this helps!
     
    BonusB, 1franck and Kirbyrawr like this.
  9. TheWarper

    TheWarper

    Joined:
    Nov 3, 2013
    Posts:
    112
    Thanks, works great
     
  10. kenli

    kenli

    Joined:
    May 20, 2013
    Posts:
    6
    Nice, thanks for explanation!
     
  11. Topillogical

    Topillogical

    Joined:
    Dec 28, 2015
    Posts:
    2
    I fixed this by adjusting my game play area (a cube containing all of the objects) to fit the camera. This way, the objects do not get distorted, the field just gets wider. Set up your cube by making the height the proper value, then this scales the width using the aspect ratio of the camera. Here is my code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class AspectAdjuster : MonoBehaviour
    5. {
    6.  
    7.     public Camera cam;
    8.     public float aspect;
    9.  
    10.     // Use this for initialization
    11.     void Start ()
    12.     {
    13.         aspect = cam.aspect;
    14.         int height = cam.pixelHeight;
    15.         int width = cam.pixelWidth;
    16.         Debug.Log ("Width: " + width + "  Height: " + height + "  Aspect: " + aspect);
    17.         transform.localScale = new Vector3 (
    18.             aspect * transform.localScale.z,
    19.             transform.localScale.y,
    20.             transform.localScale.z
    21.         );
    22.     }
    23.    
    24.     // Update is called once per frame
    25.     void Update ()
    26.     {
    27.    
    28.     }
    29. }
    30.  
     
  12. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    NECRO'd

    since precision is lost in Unity, especially it seems in the editor after .01, you can do something smelly like this:

    Code (CSharp):
    1. private void CalcAspect()
    2. {
    3.   float r = screenWidth / screenHeight;
    4.   string _r = r.ToString("F2");
    5.   string ratio = _r.Substring(0,4);
    6.  
    7.   switch(ratio)
    8.   {
    9.     case "1.33":  //4:3
    10.         break;
    11.     case "1.50": //3:2
    12.         break;
    13.     case "0.67": //2:3
    14.         break;
    15.     case "0.56": //9:16
    16.         break;
    17.   }
    18. ]
    This will also allow you to determine orientation, set this up in a helper class with events, and you're good to go.. have the events pass the aspect ratio and orientation in whatever format you like.

    I use "F2" because it seems x.ToString("F#"); likes to round for me :)
     
    Last edited: Jun 16, 2016
    p0w1nd and ben-rasooli like this.
  13. cradiff

    cradiff

    Joined:
    Feb 7, 2015
    Posts:
    66
    work nice for android too. Thanks a lot SteveJ
     
  14. ben-rasooli

    ben-rasooli

    Joined:
    May 1, 2014
    Posts:
    40
    I normally attach this utility class to my canvas:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class CanvasResolution : MonoBehaviour
    5. {
    6.     void Awake ()
    7.     {
    8.         #if ! UNITY_EDITOR
    9.         Vector2 referenceResolution;
    10.  
    11.         if (Camera.main.aspect >= 1.7)// 16:9
    12.             referenceResolution = new Vector2(960f, 540f);
    13.         else if (Camera.main.aspect > 1.6)// 5:3
    14.             referenceResolution = new Vector2(1280f, 768f);
    15.         else if (Camera.main.aspect == 1.6)// 16:10
    16.             referenceResolution = new Vector2(1280f, 800f);
    17.         else if (Camera.main.aspect >= 1.5)// 3:2
    18.             referenceResolution = new Vector2(960f, 640f);
    19.         else// 4:3
    20.             referenceResolution = new Vector2(1024, 768f);
    21.  
    22.         GetComponent<CanvasScaler>().referenceResolution = referenceResolution;
    23.         #endif
    24.     }
    25. }
     
    elpair, p0w1nd and kamathaj like this.
  15. E_Urban

    E_Urban

    Joined:
    Sep 16, 2014
    Posts:
    8
  16. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No you can't; that has nothing at all to do with this topic.

    --Eric
     
  17. ibx00

    ibx00

    Joined:
    Jul 17, 2018
    Posts:
    7
    Camera.main.aspect
     
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, Camera.aspect. Camera.main refers to a camera in the scene specifically tagged "Main Camera", not cameras in general.

    --Eric
     
  19. Necronomicron

    Necronomicron

    Joined:
    Mar 4, 2015
    Posts:
    108
    I don't see static property
    Camera.aspect
    in Unity.
     
  20. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Yeah, Camera.aspect is not a static property.

    It's a member property.

    So you need to check the aspect of the specific camera you want.

    Camera.main.aspect might be what you want if Camera.main is the camera you're interested in. Which is likely since that is the main camera which 'should' be the primary display area on screen.

    Though this is an editable property and you could set the aspect to something that is NOT the real aspect of the display. So if you're hoping to get the aspect of the view area from this... it's not going to necessarily be accurate if it's been edited at anytime.

    https://docs.unity3d.com/ScriptReference/Camera-aspect.html
     
    Necronomicron likes this.
  21. Necronomicron

    Necronomicron

    Joined:
    Mar 4, 2015
    Posts:
    108
    I would just use
    Screen.width
    and
    Screen.height
    instead.
     
  22. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Yeah, I would too.
     
    Necronomicron likes this.
  23. WookieWookie

    WookieWookie

    Joined:
    Mar 10, 2014
    Posts:
    35
    Dividing Screen.height/Screen.width equals 0 when running in the editor. Is there a way to get this working while working in Editor, so you can see the change without having to build?
     
  24. Livealot

    Livealot

    Joined:
    Sep 2, 2013
    Posts:
    228
    That's likely because you're dividing by an int instead of a float. Just cast the equation as a float and you should get the values
     
  25. Danoli3

    Danoli3

    Joined:
    Sep 12, 2017
    Posts:
    14
    Code (CSharp):
    1.                float aspect = (float)Screen.height / (float)Screen.width; // Portrait
    2.                 //aspect = (float)Screen.width / (float)Screen.height; // Landscape
    3.                 Debug.Log("Aspect Ratio:" + aspect);
    4.                 if (aspect >= 1.87)
    5.                 {
    6.                     Debug.Log("19.5:9"); // iPhone X                  
    7.                 }
    8.                 else if (aspect >= 1.74)  // 16:9
    9.                 {
    10.                     Debug.Log("16:9");
    11.                 }
    12.                 else if (aspect > 1.6)// 5:3
    13.                     Debug.Log("5:3");
    14.                 else if (Math.Abs(aspect - 1.6) < Mathf.Epsilon)// 16:10
    15.                     Debug.Log("16:10");
    16.                 else if (aspect >= 1.5)// 3:2
    17.                     Debug.Log("3:2");
    18.                 else
    19.                 { // 4:3
    20.                     Debug.Log("4:3 or other");                  
    21.                 }
    Portrait / Landscape and iPhone X
     
    HajiyevEl likes this.
  26. fwalker

    fwalker

    Joined:
    Feb 5, 2013
    Posts:
    255
    This is what I have. It feels like one of the nasties pieces of code I have written in a while :p ...
    Is there no cleaner way?


    Code (CSharp):
    1.  
    2.    private string GetAspectRatio(int aScreenWidth, int aScreenHeight)
    3.         {
    4.         float r = (float)aScreenWidth / (float)aScreenHeight;
    5.         string _r = r.ToString("F2");
    6.         string ratio = _r.Substring(0, 4);
    7.         switch (ratio)
    8.             {
    9.             case "2.37":
    10.             case "2.39":
    11.                 return ("  21:9");
    12.             case "1.25":
    13.                 return ("  5:4");
    14.             case "1.33":
    15.                 return ("  4:3");
    16.             case "1.50":
    17.                 return ("  3:2");
    18.             case "1.60":
    19.             case "1.56":
    20.                 return ("  16:10");
    21.             case "1.67":
    22.             case "1.78":
    23.             case "1.77":
    24.                 return ("  16:9");
    25.             case "0.67":
    26.                 return ("  2:3");
    27.             case "0.56":
    28.                 return ("  9:16");
    29.             default:
    30.                 return (string.Empty);
    31.             }
    32.         }
    33. }
     
    yuliyF and restush96 like this.
  27. Tedward747

    Tedward747

    Joined:
    Aug 30, 2020
    Posts:
    1
    I'm sure the code already posted in here will work for most people, but if you're looking for something that works specifically how OP asked for (or say to be able to easily display the aspect ratio in a way an end user will understand), this is what I put together:

    Code (CSharp):
    1.         private string AspectRatio(int a, int b)
    2.         {
    3.             int r;
    4.             int oa = a;
    5.             int ob = b;
    6.             while (b != 0)
    7.             {
    8.                 r = a % b;
    9.                 a = b;
    10.                 b = r;
    11.             }
    12.             return (oa/a).ToString() + ":" + (ob/a).ToString();
    13.         }

    AspectRatio(1920,1080);

    returns "16:9"


    Also TIL that 3440x1440 isn't actually 21:9 but the much less sexy 43:18
     
    HyagoOliveira and sk1zZ like this.
  28. ducalle

    ducalle

    Joined:
    Nov 5, 2021
    Posts:
    3
    Your output result is very strange, for example with Iphone 6S, I got 375:667.
     
  29. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,000
    That's not strange, that's just correct ^^. The iPhone S6 has a resolution of 750 x 1334 and the smallest common denominator is 2. So 750/2 == 375 and 1334/2 == 667. This is the reduced fraction and it can't be simplified any further. This IS the actual aspect ratio, though it's quite close to 9:16 if the screen would be one pixel smaller 750x1333. The method does calculate the "actual" aspect ratio.

    There are countless of odd screen resolutions out there, so without rounding you could always get "fancy" resolutions.
     
  30. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    I target bands of aspect ratios to determine best UI layouts dynamically, so 16:9 would be (say) from 1.7 to 1.8.

    And finally put on hard-guard AspectRatioFitters to ensure everything fits.

    Flipping resolutions in the Game window (you can create as many custom ones as you like) is also a great way to quickly test everything about your game in any arbitrary resolution / aspect you want.
     
    lordofduct likes this.