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): switch (GetAspectRatio()) { case "4:3": ... case "3:2": ... case "16:9": ... } 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?
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
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): if (Camera.main.aspect >= 1.7) Debug.Log("16:9"); else if (Camera.main.aspect >= 1.5) Debug.Log("3:2"); else Debug.Log("4:3"); It just feels kind of "cheap" or something.
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!
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): using UnityEngine; using System.Collections; public class AspectAdjuster : MonoBehaviour { public Camera cam; public float aspect; // Use this for initialization void Start () { aspect = cam.aspect; int height = cam.pixelHeight; int width = cam.pixelWidth; Debug.Log ("Width: " + width + " Height: " + height + " Aspect: " + aspect); transform.localScale = new Vector3 ( aspect * transform.localScale.z, transform.localScale.y, transform.localScale.z ); } // Update is called once per frame void Update () { } }
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): private void CalcAspect() { float r = screenWidth / screenHeight; string _r = r.ToString("F2"); string ratio = _r.Substring(0,4); switch(ratio) { case "1.33": //4:3 break; case "1.50": //3:2 break; case "0.67": //2:3 break; case "0.56": //9:16 break; } ] 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
I normally attach this utility class to my canvas: Code (CSharp): using UnityEngine; using UnityEngine.UI; public class CanvasResolution : MonoBehaviour { void Awake () { #if ! UNITY_EDITOR Vector2 referenceResolution; if (Camera.main.aspect >= 1.7)// 16:9 referenceResolution = new Vector2(960f, 540f); else if (Camera.main.aspect > 1.6)// 5:3 referenceResolution = new Vector2(1280f, 768f); else if (Camera.main.aspect == 1.6)// 16:10 referenceResolution = new Vector2(1280f, 800f); else if (Camera.main.aspect >= 1.5)// 3:2 referenceResolution = new Vector2(960f, 640f); else// 4:3 referenceResolution = new Vector2(1024, 768f); GetComponent<CanvasScaler>().referenceResolution = referenceResolution; #endif } }
No, Camera.aspect. Camera.main refers to a camera in the scene specifically tagged "Main Camera", not cameras in general. --Eric
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
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?
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
Code (CSharp): float aspect = (float)Screen.height / (float)Screen.width; // Portrait //aspect = (float)Screen.width / (float)Screen.height; // Landscape Debug.Log("Aspect Ratio:" + aspect); if (aspect >= 1.87) { Debug.Log("19.5:9"); // iPhone X } else if (aspect >= 1.74) // 16:9 { Debug.Log("16:9"); } else if (aspect > 1.6)// 5:3 Debug.Log("5:3"); else if (Math.Abs(aspect - 1.6) < Mathf.Epsilon)// 16:10 Debug.Log("16:10"); else if (aspect >= 1.5)// 3:2 Debug.Log("3:2"); else { // 4:3 Debug.Log("4:3 or other"); } Portrait / Landscape and iPhone X
This is what I have. It feels like one of the nasties pieces of code I have written in a while ... Is there no cleaner way? Code (CSharp): private string GetAspectRatio(int aScreenWidth, int aScreenHeight) { float r = (float)aScreenWidth / (float)aScreenHeight; string _r = r.ToString("F2"); string ratio = _r.Substring(0, 4); switch (ratio) { case "2.37": case "2.39": return (" 21:9"); case "1.25": return (" 5:4"); case "1.33": return (" 4:3"); case "1.50": return (" 3:2"); case "1.60": case "1.56": return (" 16:10"); case "1.67": case "1.78": case "1.77": return (" 16:9"); case "0.67": return (" 2:3"); case "0.56": return (" 9:16"); default: return (string.Empty); } } }
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): private string AspectRatio(int a, int b) { int r; int oa = a; int ob = b; while (b != 0) { r = a % b; a = b; b = r; } return (oa/a).ToString() + ":" + (ob/a).ToString(); } AspectRatio(1920,1080); returns "16:9" Also TIL that 3440x1440 isn't actually 21:9 but the much less sexy 43:18
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.
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.