unity屏幕适配
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity屏幕适配相关的知识,希望对你有一定的参考价值。
参考技术A 屏幕适配 :简单说,就是将UI以适当的尺寸显示在屏幕上的适当位置。
比如我们在手机上运行一个小游戏,打开它的菜单栏,一般都是如下画风
换一个手机,那就有可能是这个样子
现在市场上流行的像iPhone X的刘海屏,很多android手机的水滴屏,刘海屏,短刘海屏等等一系列手机,如果根据机型来适配,机型太多适配较复杂;我下面要介绍的是根据刘海屏、水滴屏等来适配,好在unity3d引擎在2017.2以上版本提供了屏幕安全区接口Screen.safeArea;
Screen.safeArea会返回移动平台安全区的Rect。例如,iPhoneX(2436x1125px)竖屏时,Screen.safeArea返回的值为Rect(0,132,2172,1125)。如图:
Screen.safeArea描述
返回屏幕的安全区域(以像素为单位)(只读)。
在某些显示器上,屏幕的某些区域可能对用户不可见。 这可能是由于显示器的形状并非矩形或是由过扫描(例如电视机屏幕)引起的。 请勿将用户界面元素放置到安全区域矩形以外的区域。 安全区域的最大大小是屏幕分辨率(以像素为单位),定义为 Rect(0, 0, Screen.width, Screen.height)。
设计思路顶部和底部设计到的UI界面尽量放到Screen.safeArea返回的Rect安全区域,如果不影响玩家点击交互的按钮可以不用放到安全区域,具体根据每个项目不同设计。为了不影响整体布局,安全区域以外可以用和背景颜色相近的图片完全填充。如下图:
很多Android上需要再Player Settings中勾选Render outside safe area,在安全区域以外渲染
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 }
以上是关于unity屏幕适配的主要内容,如果未能解决你的问题,请参考以下文章