Unity 手机屏幕适配
手机屏幕适配主要分为
1、手机安全交互区域适配(例如需要处理刘海屏)
2、界面内部UI元素相对位置适配
准备工作
1、对Canvas设置
(1)设置Render Mode为Screen Space-Camera,并赋值相机的引用
(2)设置UI Scale Mode 为 Scale With Screen Size,并设置项目分辨率
2、安装设备模拟器
(Device Simulator)
该插件可以帮助我们模拟游戏在手机上运行时的适配效果
Unity 2021之前的版本都是预览包,需要手动下载,
打开package Manager,进行设置
勾选启用预览包
搜索下载 模拟器
在Game窗口切换使用
点击Safe Area 显示设备安全区域
切换设备型号
安全区域适配
需要处理三类屏幕适配情况:
1、只需要适配上端区域
型号 |
Apple iPad Air 2 |
Google Pixel 5 |
Huawei P40 Pro |
Motorola Moto G7 Power |
OnePlus 6T |
Samsung Galaxy Note10 |
Samsung Galaxy Note10+ 5G |
Samsung Galaxy Note20 Ultra 5G |
Samsung Galaxy S10 5G |
Samsung Galaxy S10+ |
Samsung Galaxy S10e |
Samsung Galaxy Z Fold2 5G_1 |
Samsung Galaxy Z Fold2 5G_2 |
Xiaomi Mi A3 |
Xiaomi Redmi 6 Pro |
Xiaomi Redmi Note7 |
2、只需要适配下端区域
型号 |
Apple iPad Pro 11 |
Apple iPad Pro 12.9(2018) |
2、上端和下端区域都适配
型号 |
Apple iPad Air (4th generation) |
Apple iPhone 11 |
Apple iPhone 12 |
Apple iPhone 12 Pro |
Apple iPhone 12 Pro Max |
Apple iPhone 12 Mini |
Apple iPhone X |
Apple iPhone XR |
Apple iPhone XS |
Apple iPhone XS Max |
创建MatchManager
using UnityEngine;
using UnityEngine.UI;
public enum MatchDimension
{
None = 1,
Width = 2,
Height = 3
}
public class MatchManager : MonoBehaviour
{
private CanvasScaler _canvasScaler;
private RectTransform _canvasRect;
const float DesignW = 1080;
const float DesignH = 1920;
private float DesignRatio; //标准参考比率
private float screenWidth; //手机屏幕宽度
private float screenHeight; //手机屏幕高度
private float safeAreaX;
private float safeAreaY;
private float safeAreaWidth; //手机安全区域宽度
private float safeAreaHeight; //手机安全区域高度
private float CanvasRectWidth => _canvasRect == null ? DesignW : _canvasRect.rect.width;
private float CanvasRectHeight => _canvasRect == null ? DesignH : _canvasRect.rect.height;
void Start()
{
_canvasScaler = GetComponent<CanvasScaler>();
_canvasRect = GetComponent<RectTransform>();
if (_canvasScaler == null)
{
var canvasObj = GameObject.Find("/GameRoot/UIRoot");
if(canvasObj!=null)
{
_canvasScaler = canvasObj.GetComponent(typeof(CanvasScaler))as CanvasScaler;
_canvasRect = canvasObj.GetComponent<RectTransform>();
}
}
if (_canvasScaler.matchWidthOrHeight == 0)
{
if (CanvasRectHeight <= DesignH)
{
//需要改为高度适配
ChangeReference((int)MatchDimension.Height);
}
}
else if (NumberTool.IsSameFloat(_canvasScaler.matchWidthOrHeight,1))
{
if (CanvasRectWidth <= DesignH)
{
//需要改为宽度适配
ChangeReference((int)MatchDimension.Width);
}
}
InitConfigData();
}
/// <summary>
/// 初始化适配时需要的配置数据
/// </summary>
private void InitConfigData()
{
DesignRatio = DesignW / DesignH;
var factRatio = CanvasRectHeight / Screen.height;
safeAreaX = Screen.safeArea.x*factRatio;
safeAreaY = Screen.safeArea.y*factRatio;
safeAreaWidth = Screen.safeArea.width*factRatio;
safeAreaHeight = Screen.safeArea.height*factRatio;
screenWidth = CanvasRectWidth;
screenHeight = CanvasRectHeight;
}
/// <summary>
/// 切换参考维度
/// </summary>
public void ChangeReference(int md)
{
if (_canvasScaler == null)
{
return;
}
if (md == (int)MatchDimension.Width)
{
_canvasScaler.matchWidthOrHeight = 0;
}
else if (md == (int)MatchDimension.Height)
{
_canvasScaler.matchWidthOrHeight = 1;
}
}
/// <summary>
/// 限制UI元素在安全区域
/// </summary>
public void LimitSafeArea(RectTransform rect)
{
var offset = screenHeight - safeAreaHeight;
if (safeAreaY == 0)
{
if (offset > 0)
{
//仅需适配屏幕top
rect.offsetMax = new Vector2(rect.offsetMax.x, rect.offsetMax.y-offset);
}
}
else
{
if ((int)offset == (int)safeAreaY)
{
//仅需适配屏幕bottom
rect.offsetMin = new Vector2(rect.offsetMin.x, rect.offsetMin.y + offset);
}
else if ((int)offset > (int)safeAreaY)
{
//需适配屏幕top和bottom
var bottomOffset = safeAreaY;
var topOffset = screenHeight - safeAreaHeight - bottomOffset;
rect.offsetMin = new Vector2(rect.offsetMin.x, rect.offsetMin.y + bottomOffset);
rect.offsetMax = new Vector2(rect.offsetMax.x, rect.offsetMax.y -topOffset);
}
}
}
}
将该脚本附加到Canvas节点上
创建MatchUIContent
using UnityEngine;
public class MatchUIContent : MonoBehaviour
{
void Start()
{
var rect = GetComponent<RectTransform>();
MatchManager.Instance.LimitSafeArea(rect);
}
}
在界面预制体中创建一个单独的节点main,在该节点下进行界面拼接
把MatchUIContent 脚本附加在Main节点上
UI界面适配
主要是处理界面内UI节点间的对齐关系
主要有16种对齐方式
1、点对齐:长宽不变,位置移动,跟随对齐点适配
2、中心点对齐:长宽不变,位置不移动
3、拉伸对齐:长或宽会变,中心位置不移动,跟随界面拉伸
提示:拼接好界面后,多通过手机模拟器界面查看测试,如果遇到界面不适配的情况,就去进行调整。