3

I have build some custom UI scaling features for a mobile app built in Unity to compensate for various phone screen ratios. I would also like protection against screen size changes, as with the rise of foldable phones, I presume that is a risk.

The preliminary solution I have implemented is to have a script attached to the objects that must potentially resize, structured like this:

public class ScreenElementSizer : MonoBehaviour {

    private int screenWidth_1 = Screen.width;
    private int screenHeight_1 = Screen.height;

    // Start is called before the first frame update
    void Start() {
        ScreenResized();
    }

    // Resizing functions here
    private void ScreenResized() {
    }

    // On every screen refresh
    void Update()
    {
        if ((Screen.width != screenWidth_1) || (Screen.height != screenHeight_1)) {
            ScreenResized();
            screenWidth_1 = Screen.width;
            screenHeight_1 = Screen.height;
        }
    }

As you can see it's a pretty simple solution where I'm storing the prior sample's Screen.width and Screen.height in variables (screenWidth_1 & screenHeight_1), then comparing them on each sample (update) and if there is a discrepancy (screen change) trigger the resizer script.

It works fine of course. I think this is pretty standard coding logic. It's probably not expensive to run one/two extra if statements like this per object per sample.

I'm just new to Unity and wondering if there's any better, built in, or more efficient way to do this task.

To be clear, I am aware of the built in canvas resizer tools that scale based on width and height. I specifically am referring to the case where you want to apply some special script based resizing logic like this when the screen size changes.

Thanks for any thoughts.

mike
  • 131
  • 10
  • I don't know of any built-in event for screen width/height change. What you did seems to be the common way of handling it. My general advice would be to not worry too much about optimization before you actually see that there are any performance issues :) – BFyre Oct 28 '21 at 11:38
  • https://stackoverflow.com/questions/61712096/in-unity-how-to-detect-if-window-is-being-resized-and-if-window-has-stopped-res ... there is no built-in event for that – derHugo Oct 28 '21 at 12:47
  • Thanks BFyre. Sometimes I wonder if I'm doing things "the crazy way" or "the rational way." Good to know this is not necessarily the crazy way. Cheers. :) – mike Oct 28 '21 at 23:18

1 Answers1

2

There is no built-in event, but you can make your own event.

DeviceChange.cs -

using System;
using System.Collections;
using UnityEngine;
 
public class DeviceChange : MonoBehaviour 
{
    public static event Action<Vector2> OnResolutionChange;
    public static event Action<DeviceOrientation> OnOrientationChange;
    public static float CheckDelay = 0.5f; // How long to wait until we check again.
 
    static Vector2 resolution;                    // Current Resolution
    static DeviceOrientation orientation;        // Current Device Orientation
    static bool isAlive = true;                    // Keep this script running?
 
    void Start() {
        StartCoroutine(CheckForChange());
    }
 
    IEnumerator CheckForChange(){
        resolution = new Vector2(Screen.width, Screen.height);
        orientation = Input.deviceOrientation;
 
        while (isAlive) {
 
            // Check for a Resolution Change
            if (resolution.x != Screen.width || resolution.y != Screen.height ) {
                resolution = new Vector2(Screen.width, Screen.height);
                if (OnResolutionChange != null) OnResolutionChange(resolution);
            }
 
            // Check for an Orientation Change
            switch (Input.deviceOrientation) {
                case DeviceOrientation.Unknown:            // Ignore
                case DeviceOrientation.FaceUp:            // Ignore
                case DeviceOrientation.FaceDown:        // Ignore
                    break;
                default:
                    if (orientation != Input.deviceOrientation) {
                        orientation = Input.deviceOrientation;
                        if (OnOrientationChange != null) OnOrientationChange(orientation);
                    }
                    break;
            }
 
            yield return new WaitForSeconds(CheckDelay);
        }
    }
 
    void OnDestroy(){
        isAlive = false;
    }
 
}

Implementation -

DeviceChange.OnOrientationChange += MyOrientationChangeCode;
DeviceChange.OnResolutionChange += MyResolutionChangeCode;
DeviceChange.OnResolutionChange += MyOtherResolutionChangeCode;
 
void MyOrientationChangeCode(DeviceOrientation orientation) 
{
}
 
void MyResolutionChangeCode(Vector2 resolution) 
{
}

Credit - DougMcFarlane

Srejon Khan
  • 438
  • 2
  • 8