UGUI轴点 锚点 自适应

这次的讨论总会让我想起我之前的一个需求,一个类似于俄罗斯方块的拼图功能(少前的芯片功能,懂的应该知道需求是什么了,有些地方不太一样,但大体是一致的),当时纠结了很长时间,最终成品也不是很完美,最后是准备用3D模型取代的,当然项目没了就没再继续了。

当时为了旋转和自动吸附的问题想了很久,因为手机上操作要尽量简便和精准,触摸操作影响其实很大

对于蓝色三格L的方块来说,裁剪下来的图片算上alpha通道实际是四格,它的旋转轴心在正方形的四个点上;对于红色四格L的方块,算上alpha通道实际却是六格,旋转轴心是在正方形边长的中点。

那么就会出现一个问题,我们如果都按照他们各自的物理旋转轴来做旋转,那么红色四格L在旋转过后并不能贴合现有的棋盘格,所以之后我们就和美术策划商量,规定所有素材的L型都要满足两个标准:Alpha通道的部分必须在左上角;所有旋转的轴心都是L型坐标轴0,0的位置。这样做数据结构上能统一,方便我们的计算,同时旋转后必定是和棋盘格对齐的。

两个方块旋转轴心我分别用不同的颜色标注出来了,最终我们的预制体都重新设置了一遍轴心

 

RectTransform

我们之前提到过,UGUI是基于RectTransform来做变换和排版的。那么就会涉及到下面几个参数。

轴点Pivot

用于旋转的轴点,矩形的左下角为坐标原点(0,0),右上角为(1,1),坐标范围在0~1之间,默认都是(0.5,0.5)。

轴点就是旋转轴所在的位置,这个我们刚刚也说到了,所以修改轴点的位置就等于修改旋转轴的位置。

锚点Anchors

注意,英文带s,锚点其实并不是一个点,而是两个点。范围一样0~1,左下角(0,0)右上角(1,1)。

minX maxX 是矩形锚点最左和最右的距离 minY maxY 是矩形锚点最下和最上的距离

要理解锚点这一概念会有些抽象,它比较类似于一个父物体下的矩形(但实际上并非存在的矩形)四条边相对于父物体四条边的距离。

我们可以试着将锚点的数值调成下面这个样子:

离最左边和最下边都距离10%,最右边和最上边都距离90%
锚点形成的矩形距离父物体四条边都是10%

这意味着什么呢,意味着现在当屏幕实际显示比例发生变化的时候,子物体相对于父物体的四条边的距离都会保持显示尺寸的10%,我们可以试试把Game窗口改成Free Aspect并调整窗口大小。

拉伸后锚点相对于父物体四条边的距离仍然保持我说的显示尺寸的10%

我想你应该可以联想到一些自适应相关的东西了,锚点对于自适应来说意义重大。

轴点和锚点都是(0.5,0.5),但因为自身不是一个正方形且发生位移,所以并非在同一位置

我们回过头来看看RectTransform现在的情况,会发现有些地方不一样了。

注意到了吗,上方的属性发生了变化
当你默认创建出来的属性是PosX PosY Width Height

锚点重合的时候,子物体不缩放,pivot到anchor的距离是相等的,此时出现的属性:

Pos(X,Y,Z):轴心点(中心点)相对锚点的位置

不重合,形成锚框,属性会发生变化:

Left/Top/Right/Bottom:矩形边缘相对于锚点的位置,当锚点分离时会出现这些内容。子物体四个角到锚点的距离永远都是相等的。最简单的例子,锚框就是整个父物体,那子物体的矩形就永远保持和父物体大小一致,最常应于面板的背景。

九宫格(十六宫格)

对应了自适应中需要考虑的常用情况

九宫格的部分实际上代表的是我们刚刚说的锚点重合没有锚框形成的情况。

另外7格则是锚框的部分,都会带有蓝色双箭头,意思是会发生缩放。

例如右上:离上面的距离保持不变 自身高度不变 长度会缩放

例如右:到两边的距离不变 自身高度不变 长度会缩放

对于UI中的元素,一般来说,如果适用的设备尺寸相差不会很多的话(例如基本都是2K 2.5K这种的),按钮,图标之类的元素,我们就不会去缩放它,而是保持原比例,当然具体情况很难讲,实际上大部分元素都需要去缩放自身来进行一定程度的自适应。十六宫格的存在就能够帮我们应对几乎所有需求了,通过父子物体的组合加上十六宫格的设定,我们能够组合出能适应复杂自适应需求的UI,当然,还需要多多实验,也有可能要引进额外参数。

异形屏自适应

这一点我讲的也不太好,大家做个参考即可。我还是会以手游为主,PC屏幕尺寸相对来说比较固定,也不会有很变态的存在,做自适应的难度相比手机和平板还是会低一些的。

多尺寸插件 Device Simulator

根据打包平台的不同,Unity实际上会给我们一组样例的显示尺寸,安卓打包下这一组会发生变化

但是图片中的还远远不够,特别是对于手机和平板来说,奇奇怪怪的尺寸可有太多了,挖孔的,曲面的,刘海的,折叠屏的,你能想到的几乎全都有,并且这些手机用户都是你的目标用户,你得去针对他们都做适配,这真的是一件很折磨人的事情。所以我要介绍一下Unity的这个插件,它根据机型来改变显示尺寸,不需要打包到真机就能够看到效果,对于我们做适配来说真的是再方便不过了。

我们可以直接在包管理器中下载
有很多已经预设好的机型,你也可以添加自定义的机型进去

具体自定义我就不在这提了,可以自己翻阅文档来进行了解。

docs.unity3d.com/Packages/[email protected]/manual/index.html

安全区 Safe Area

除去那些不可使用的部分,玩家实际可以进行触屏操控的部分。通常我们就要把UI的可交互元素放置在安全区内,毕竟你不希望玩家使劲戳一个按不到的按钮吧?所以这里我们就会有一个最基本的原则,通过锚点保证UI元素都在安全区,而背景缩放后裁切,保证不被拉伸。

勾上上方的安全区按钮,可以发现iphone xs的安全区需要扣除刘海和下方的一部分,为啥呢?
华为p40 pro 下方倒是划成安全区部分了,但是那个圆角还是挺扎眼的

横向宽高比 ScreenRatio

手机设备屏幕处于横向状态下的宽度和高度之比,我们通常用这个来衡量做适配的权重。

一般来说,美术会敲定一版设计时的宽高比,之后我们所有的适配都是基于这一版设计宽高比来做的,例如说当时我们项目用的设计尺寸是2340*1080,之后我们遇到的实际宽高比,都会基于此进行锚点的定位和缩放。

Canvas Scaler

这里的ScaleMode选择了根据屏幕尺寸缩放,参考的分辨率则是1920*1080,并且完全高度适配

这里的设定算是比较常见的一个自适应的配置。Canvas的缩放决定了UI在缩放后发生的最终的变化,例如这里的设置,只有高度会产生影响,宽度的变化不会有任何影响。我录了一个视频来展示背景在不同情况下的变化,一开始是Match为0,也就是以宽度为准,后来是Match为1,以高度为准。

可以看到,在宽度适配下,宽度的拉伸会导致背景也跟着进行拉伸,如果显示的宽度远远不足于背景的宽度,背景并不会对宽度进行裁切,而是进行缩放,导致上下出现黑边。此时如果我们调整高度,使高度低于背景高度,图片会受到裁切。

同理,在高度适配下,高度的拉伸会导致背景也跟着进行拉伸,如果显示的高度远远不足与背景的高度,背景会进行缩放。此时我们调整宽度,当宽度小于当前背景的宽度时,会进行裁切。

自适应的策略

在通过上面几个概念的介绍后,我想你应该有一些自己的想法了。这里我所讲的策略只是个人见解,具体实施的话需要多和美术这里沟通,确保满足最终的效果。

设计宽高比 大于 实际宽高比:优先做宽度适配,也就是说上下有黑边,然后再拉伸。

设计宽高比 小于 实际宽高比:优先做高度适配,也就是说左右有黑边,然后再拉伸。

遇到刘海,全面屏,宽屏,可能上下左右都有死区的,两种方案:

拉伸元素的图片,超出开发时候划定的区域,缩放的时候就会符合。

修改锚点,让锚点永远都在边界,拉伸的时候就会左对齐。

例如上面就是拉伸背景来起到和锚点对齐一致的效果

总之通过画布的自适应缩放以及锚点对齐的组合,再加上用多个分辨率去检验元素是否在安全区内,足以应对异形屏自适应这个问题。当然我这里说的很简单,实际操作起来真的很累人。

此外还有一个比较取巧的方法,就是去让玩家帮你做这件事,这我就不得不提我之前看到明日方舟的适配方案了,真的是有点摆烂的,他们在设置里添加了一个选项,让玩家自己去调整UI的缩放,相当于让玩家来替代自适应算法,我觉得,怎么说呢,不是不行,但是很微妙。

实际上我觉得应该给两个,这个只是x轴,曲面屏在手机横屏的时候上下也有死区

我看到有玩家在吐槽这个 禁止大黑边!《明日方舟》异形屏UI适配的改进方案建议,还是挺感慨的。

总之,自适应啥的,也算是一个老大难问题了,我觉得光凭这篇文章还远远不够,我自己也是搞不好这个,大家参考过后还是要多多实践,自己踩过坑才明白该怎么搞这个问题。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注