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.
CodePudding user response:
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