在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 }
