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 }
posted @ 2021-09-24 08:10  赵不灰  阅读(5865)  评论(0编辑  收藏  举报