unity — 屏幕适配(异形屏)
在Unity 2019.3 (beta)及其后版本可用 Device Simulator包,预设大部分机型,也可以自定义机型, 可以模拟机型的分辨率和刘海屏,非常方便做UI适配(现在刘海屏、水滴屏、挖空屏··· 各种屏,适配起来超级麻烦,Device Simulator功能,无需打包到真机就能看适配,方便!
打开方式:Package Manager包管理器下载,WIndow => General => Device Simulator
Screen.safeArea 会返回移动平台安全区的Rect。例如,iPhonex(2436x1125 px)横屏时,Screen.safeArea返回的值为Rect(132,63,2172,1062)。如图1-1:
图1 - 1
适配情况处理:
1. UI是全屏背景,把背景放在安全区域外,其他UI组件放在安全区域内。
2.适配需要靠边的UI ,把UI 拉长到屏幕外,达到适配效果,例如图1-2:返回按钮、玩家资产的背景图
3.无全面背景,四个角,或者上下,左中、右中,直接调整锚点进行适配。
图 1 - 2
那么安全区域SafeArea的数值已知,以iphonex为例:那么safeArea的anchor x轴最小值是:132 / 2436 = 0.05418,x轴最大值就是 1 - 0.05418。如图 1-3
图 1- 3
在iphonex模拟机上,左右两边有很多空白,经多次测试,用132的一半66除以屏幕宽即可,这样两边不会有太多的空白。把SafeAreaRect.cs挂在SafeArea物体上面就可以啦, 代码如下:
1 using System; 2 using UnityEngine; 3 4 5 [DisallowMultipleComponent]//用于MonoBehaviour或其子类,不能重复添加这个类的组件,重复添加会弹出对话框 6 [RequireComponent(typeof(RectTransform))] 7 public class SafeAreaRect: MonoBehaviour 8 { 9 [NonSerialized] 10 private RectTransform _rect; 11 protected RectTransform rectTransform 12 { 13 get 14 { 15 if (_rect == null) 16 _rect = GetComponent<RectTransform>(); 17 return _rect; 18 } 19 } 20 21 public static Rect cacheSafeArea = Rect.zero; 22 private void Awake() 23 { 24 if (cacheSafeArea == Rect.zero) 25 cacheSafeArea = GetSafeArea(); 26 27 ApplySafeArea(cacheSafeArea); 28 } 29 30 private Rect __screenSafeArea = Rect.zero; 31 private void Update() 32 { 33 if (__screenSafeArea != Screen.safeArea) 34 { 35 cacheSafeArea = GetSafeArea(); 36 ApplySafeArea(cacheSafeArea); 37 } 38 } 39 40 /// <summary> 41 /// 获取当前屏幕的参数 42 /// </summary> 43 private float[] GetCustomerSceneParam() 44 { 45 float[] sceneParam = new float[3]; 46 sceneParam[0] = Screen.width; 47 sceneParam[1] = Screen.height; 48 sceneParam[2] = Screen.safeArea.x * 0.5f; 49 return sceneParam; 50 } 51 52 private Rect GetSafeArea() 53 { 54 float x = 0, y = 0, w = 1, h = 1; 55 float[] param = GetCustomerSceneParam();//width、height、异性高度 56 var orientation = Screen.orientation;//获取屏幕方向 57 if (orientation == ScreenOrientation.Portrait || orientation == ScreenOrientation.PortraitUpsideDown) 58 { //竖屏 59 y = param[2] / param[0]; 60 h = 1 - y; 61 } 62 else 63 { //横屏 64 x = param[2] / param[0]; 65 w = 1 - x; 66 } 67 return new Rect(x, y, w, h); 68 } 69 70 private void ApplySafeArea(Rect rect) 71 { 72 #if UNITY_EDITOR 73 __screenSafeArea = Screen.safeArea;//安全区域 74 #endif 75 rectTransform.anchorMin = rect.position;//rect.position的x、y轴最小值(对用的是rect(x,y)) 76 rectTransform.anchorMax = rect.size;//rect.size也就是x、y轴最大值(对用的是rect(w,h)) 77 } 78 }
旋转问题 图1-4:
图1-4
Default Orientation* Auto Roation:表示游戏支持自动旋转屏幕,但是前提是手机没有锁定屏幕旋转功能。
Landscape Right 和Landscape Left:表示手机屏幕只支持横屏两个方向的自动旋转。
Portrait 和 PortraitUpsideDown :表示竖屏、竖屏且上下颠倒
安卓横屏默认旋转为:Home键右手,导致如果右下角有操作,会不小心碰着返回按钮,影响玩家的体验。所以我们可以这么设置:
unity编辑器上系统设置:默认为 右横屏。
通过代码,在Awake或者start中设置 横屏旋转:
1 void Start ()
2 {
3 //设置屏幕自动旋转, 并置支持的方向
4 Screen.orientation = ScreenOrientation.AutoRotation;
5 Screen.autorotateToLandscapeLeft = true;
6 Screen.autorotateToLandscapeRight = true;
7 Screen.autorotateToPortrait = false;
8 Screen.autorotateToPortraitUpsideDown = false;
9 }