Scaling and Fitting a Screen Space UI for Multiple Orientations/ Resolutions

Check out this document on ui element positioning!

https://docs.unity3d.com/Manual/HOWTO-UIMultiResolution.html

Screen space UI exists on/in the dimensions of the screen / viewport. Think of the screen as a glass window that you are seeing the world on the other side of. UI elements are attached to this window like decals and move with it.

World space UI, on the other hand, puts the UI elements in the virtual world, and they can interact with the objects in said world, behind the glass window.

Assume we are using a screen space UI in “camera” mode.

The first question we must ask ourselves: What are our UI elements and where do we want them to be placed.

  1. Create a canvas object: Create → UI -> Canvas
  2. Set mode to Screen space -camera. Set main camera as “render camera” field.
  3. Set the plane distance so the canvas rectangle more or less fits your screen area
  4. Add a “Canvas Scaler” component. Add component → Layout → Canvas Scaler
  5. Scale mode: Scale with Screen Size
  6. Create some UI objects and child them to the Canvas object
  7. Place said objects roughly where we want them to be on screen.Screenshot (31)
  8.  Anchor objects: use your best judgement. Understand that anchoring something to a particular side means that it will always be as far away from that side proportionally as it currently is. No matter if you change aspect ratio/ resolution.
  9. Use this code to detect screen orientation change. Basically, it checks whether the canvas rect transform dimensions have changed
    using UnityEngine;
    using UnityEngine.Events;
     
    [RequireComponent(typeof(RectTransform))]
    public class ScreenWatcher : MonoBehaviour
    {
        static ScreenWatcher instance = null;
        public static ScreenWatcher Instance { get { return instance; } }
        static UnityEvent OnResolutionChange = null;
        static UnityEvent OnOrientationChange = null;
        static Vector2 resolution; // Current Resolution
        static ScreenOrientation orientation; // Current Screen Orientation
     
        static void init()
        {
            if (instance != nullreturn;
     
            resolution = new Vector2(Screen.width, Screen.height);
            orientation = Screen.orientation;
     
            OnResolutionChange = new UnityEvent();
            OnOrientationChange = new UnityEvent();
            GameObject canvas = new GameObject("ScreenWatcher");
            canvas.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
            instance = canvas.AddComponent<ScreenWatcher>();
            DontDestroyOnLoad(canvas);
        }
     
        private void Start()
        {
            if (instance != this)
            {
                Destroy(this);
            }
        }
     
        private void OnRectTransformDimensionsChange()
        {
            // Check for an orientation change.
            ScreenOrientation curOri = Screen.orientation;
            switch (curOri)
            {
                case ScreenOrientation.Unknown: // Ignore
                {
                    break;
                }
                default:
                {
                    if (orientation != curOri)
                    {
                        orientation = curOri;
                        OnOrientationChange.Invoke();
                    }
                    break;
                }
            }
     
            // Check for a resolution change.
            if ((resolution.x != Screen.width && resolution.x != Screen.height) || (resolution.y != Screen.height && resolution.y != Screen.width))
            {
                resolution = new Vector2(Screen.width, Screen.height);
                OnResolutionChange.Invoke();
            }
        }
     
        public static void AddResolutionChangeListener(UnityAction callback)
        {
            init();
            OnResolutionChange.AddListener(callback);
        }
     
        public static void RemoveResolutionChangeListener(UnityAction callback)
        {
            OnResolutionChange.RemoveListener(callback);
        }
     
        public static void AddOrientationChangeListener(UnityAction callback)
        {
            init();
            OnOrientationChange.AddListener(callback);
        }
     
        public static void RemoveOrientationChangeListener(UnityAction callback)
        {
            OnOrientationChange.RemoveListener(callback);
        }
     
        private void OnDestroy()
        {
            if (instance == this)
            {
                // Clean up memory.
                OnResolutionChange.RemoveAllListeners();
                OnResolutionChange = null;
                OnOrientationChange.RemoveAllListeners();
                OnOrientationChange = null;
                instance = null;
            }
        }
    }
  10.  Create a handler in some Monobehaviour and add it to the listener in Screenwatcher:
    ScreenWatcher.AddOrientationChangeListener(OnOrientationChanged);
    
    ...rest of file
    
    public void OnOrientationChanged(){
    Debug.Log ("Orientation changed!");
    if (Screen.orientation == ScreenOrientation.Landscape) {
    Debug.Log("Landscape Mode!");
    Camera.main.fieldOfView = 60f;
    Camera.main.transform.position = new Vector3 (0f, 0f, -3f);
    } else {
    Debug.Log ("portrait mode!!!");
    Camera.main.fieldOfView = 120f;
    Camera.main.transform.position = new Vector3 (1f, 2f, -3f);
    }
    GameObject.Find ("YourCanvasNameHere").GetComponent<CanvasScaler> ().referenceResolution = new Vector2 (Screen.width, Screen.height);
    
    }
  11. Change object positions, camera position, and camera field of view in this method to achieve useful organization of objects based on screen orientation.
  12.  Don’t forget to change the reference resolution each time, as the screen resolution changes!
  13. Test with your favorite android devices, or BlueStacks, or Android Studio device emulator!
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s