找回密码
 立即注册
查看: 413|回复: 0

Unity UI适配方案

[复制链接]
发表于 2022-2-14 18:15 | 显示全部楼层 |阅读模式
设计目的


  • UI必须充满屏幕,不能有黑边
  • UI必须在屏幕中,不能超出屏幕
  • UI在多分辨率下的位置和尺寸保持一致
  • UI不能变形
名词

设计分辨率:内容生产者在制作场景时使用的分辨率蓝本,例如该项目采用的 1280 x 720
通常设计分辨率会采用市场目标群体中使用率最高的设备的屏幕分辨率,比如目前安卓设备中 800 x 480 和 1280 x 720 两种屏幕分辨率,或 iOS 设备中 1136 x 640 和 960 x 640 两种屏幕分辨率。这样当美术或策划使用设计分辨率设置好场景后,就可以自动适配最主要的目标人群设备。
屏幕分辨率:游戏在设备上运行时的实际屏幕显示分辨率,例如小米6手机 1920 x 1080
SafeArea:一个可视窗口范围,处于安全区域的内容不受圆角(corners)、齐刘海(sensor housing)、小黑条(Home Indicator)的影响。


Pixels Per Unit(PPU):该精灵图多少个像素对应于世界空间中一个单位,该值默认为100
在Unity中,一个世界单位=1m。
原理

UI适配,就是根据设计分辨率和不同的屏幕分辨率,在遵循设计目的前提下,最大程度还原UI设计样式的过程。
假设我们的设计分辨率为 800 x 480,美术制作了一个同样分辨率大小的背景图像。


设计分辨率和屏幕分辨率宽高比相同

在屏幕分辨率的宽高比和设计分辨率相同时,假如屏幕分辨率是 1600 x 960,正好将背景图像放大 1600/800 = 2 倍 就可以完美适配屏幕。
设计分辨率宽高比大于屏幕分辨率,适配高度避免黑边

假设屏幕分辨率是 1024 x 768,在下图中以红色方框表示设备屏幕可见区域。我们使用 Canvas 组件提供的的 适配高度 模式,将设计分辨率的高度自动撑满屏幕高度,也就是将场景图像放大到 768/480 = 1.6 倍


这是设计分辨率宽高比大于屏幕分辨率时比较理想的适配模式,如上图所示,虽然屏幕两边会裁剪掉一部分背景图,但能够保证屏幕可见区域内不出现任何穿帮或黑边。可以通过 Widget(对齐挂件)调整 UI 元素的位置,来保证 UI 元素出现在屏幕可见区域里。

这是设计分辨率宽高比大于屏幕分辨率时比较理想的适配模式,如上图所示,虽然屏幕两边会裁剪掉一部分背景图,但能够保证屏幕可见区域内不出现任何穿帮或黑边。可以通过 Widget(对齐挂件)调整 UI 元素的位置,来保证 UI 元素出现在屏幕可见区域里。

设计分辨率宽高比小于屏幕分辨率,适配宽度避免黑边

假设屏幕分辨率是 1920 x 960,同样在下图中以红色方框表示设备屏幕可见区域。我们使用 Canvas 组件提供的 适配宽度 模式,将设计分辨率的宽度自动撑满屏幕宽度,也就是将场景放大 1920/800 = 2.4 倍


在设计分辨率宽高比较小时,使用这种模式会裁剪掉屏幕上下一部分背景图。
不管屏幕宽高比如何,完整显示设计分辨率中的所有内容(目前项目采用方案)

该方案根据不同屏幕长宽比,动态调整适配规则来处理以上三种情况。由于需要完整显示设计分辨率中的所有内容(核心内容在 1280 x 720 中),所以可能出现黑边的情况。故采用的设计分辨率为 1280 x 720,但是底图分辨率扩大到 1656 x 960,在一定范围内减少出现黑边的情况。
我们屏幕分辨率假设为 640 x 960 的竖屏,如果要确保背景图像完整的在屏幕中显示,需要同时开启 Canvas 组件中的 适配高度适配宽度,这时场景图像的缩放比例是按照屏幕分辨率中较小的一维来计算的,在下图的例子中,由于屏幕宽高比小于 1,就会以宽度为准计算缩放倍率,即 640/800 = 0.8 倍


在这种显示模式下,屏幕上可能会出现黑边,或超出设计分辨率的场景图像(穿帮)。尽管一般情况下开发者会尽量避免黑边,但如果需要确保设计分辨率范围的所有内容都显示在屏幕上,也可以采用这种模式。
实现

根据以上原理,我们需要初始化设计分辨率,并根据设计分辨率与不同的屏幕分辨率之间宽高比,来动态变更适配规则。
适配规则



通过AutoCavasScalerAdjustor脚本动态调整Canvas Scaler的Match规则:


设计分辨率



Canvas Scaler脚本通过修改Canvas组件的ScaleFactor参数来维持设计分辨率。
假如当前屏幕分辨率为 1656 x 960 时,Match规则为适配宽度时,则ScaleFactor=1656 / 1280 = 1.29375005,此时经过适配规则下得到:适配分辨率= (1656 / 1.29375005,960 / 1.29375005)~= (1280,742.0289)。
PixelsPerUnit



Canvas Renderer

在UGUI中,PPU只作用于Image Sliced和Image Tiled,用于确定九宫格拉伸像素比例;其他Sprite绘制不受PPU影响,按组件rectTransform.rect进行绘制。


Sprite Renderer

在2D系统中,Sprite绘制受到PPU数值影响。
例如一张Sprite长宽分别为 1656 x 960,其PPU = 100,则通过Sprite Renderer绘制的Sprite大小相当于世界空间 16.56 x 9.6。




Canvas RectTransform缩放比例
为了保证Canvas Root及其子节点满足RectTransform的 1 Unit相当于 1 px。
正交摄像机

假如当前实际分辨率 1280 x 720,Camera为正交模式,orthographicSize = 60


根据计算公式可得:缩放比例 = orthographicSize * 2 / Screen.Height = 60 * 2 / 720 = 0.1666667


透视摄像机

假如当前实际分辨率 1280 x 720,Camera为透视模式,Field Of View = 60,摄像机距离UI画布 distance = 100


根据计算公式可得:

  • halfHeight = distance * tan(fov) = 100 * tan(30) ~= 57.73503
  • 缩放比例 = halfHeight * 2 / Screen.Height = 57.73503 * 2 / 720 ~= 0.1603751


异形屏适配

目前屏幕尺寸 > 2.1的情况下,长度会收缩 80 个像素(以后需要修改成读取 SafeArea 参数)


参考文档

https://blog.csdn.net/LeZhi_/article/details/78827549
Cocos UI系统

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-16 22:34 , Processed in 0.214384 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表