↑ 返回顶部

0,简介 链接到标题

之前被 Unity 的 UI 布局之类的整得特别崩溃,总之是想写一篇文章稍微总结一下学到的新东西和踩过的一堆坑,就直接从最基础的开始总结

以及 Unity 官方的 UI 大概是有三种类型:最早期的 IMGUI (通常直接称为 GUI ),本文中会总结的 UGUI (官方文档中称为 Unity UI ),以及最新的 UI 系统 UI Toolkit (2021版本后可使用),它比较贴近于 web 前端

1,Canvas 链接到标题

首先建立一个新场景的时候,里边除了 Main Camera和 Direct Light 以外啥也没有。

这时候开始搓ui的话,要新建一个 Canvas 画布,UGUI 中所有的 UI 元素都必须作为 Canvas 的子物体才能被渲染。

创建 Canvas 对象

Canvas 有几种不同的渲染模式:

Overlay 模式下,该画布中的所有元素都会被渲染在最上层,不受任何相机影响,这个模式通常用于制作 UI 界面

Camera 模式下,UI 将在指定相机前方的固定距离处渲染,这个画布中的 UI 将和 3D 场景之间有前后遮挡关系,同时由于 UI 由相机渲染,所以可以对 UI 添加后处理效果 (可以暂且理解为,当需要不同的 UI 做出层级穿插的效果,但是这些 UI 也不是放在 3D 场景中的那种 UI,就可以采用这个渲染模式,例如某些游戏的角色装备界面中,需要人物模型插在两层 UI 的中间进行展示,这里不再做其他延申)

World Space 模式中,UI 作为 3D 世界中的物体存在

接下来我主要以 Overlay 渲染模式为前提展开讲解(因为主要涉及到个人搭 UI 时的经验)

2,Canvas Scaler 与 Graphic Raycaster 链接到标题

创建完 Canvas 之后会发现,对象上还会自带挂载两个组件:Canvas Scaler 与 Graphic Raycaster。

先来讲讲 Canvas Scaler,这个组件用于让 UI 在不同分辨率的屏幕上保持相同的显示效果。它拥有三种不同的 UI Scale Mode,默认是 Constant Pixel Size,也就是 UI 元素像素尺寸始终不变,不随屏幕分辨率改变。另外一种不常用的是 Constant Physical Size,就是 UI 元素的物理尺寸不变,固定像素大小,仅根据屏幕的 DPI (每英寸像素数)调整像素数量,似乎一般只在检测工具类应用中使用。这两种运用的场景相比 Scale With Screen Size 来说较少,因此这里不再深入讨论

Canvas Scaler 的不同显示方式

接下来要介绍的是对 UI 自适应非常重要的模式——Scale With Screen Size。该模式下 UI 会根据参考分辨率(Reference Resolution)判断 UI 的缩放比例。

要想实现 UI 的自适应,就一定要在一开始建完项目初始化 Canvas 的时候设置好这个模式!!最好在开发过程中保持 Game 窗口的分辨率和参考分辨率完全一致!!(不然后面没能适配好的 UI 一多不一定好更改!!)

相比下来 Graphic Raycaster 的作用则完全不同,但也不用开发者另外去设置什么了(比上面那个方便)。它会在用户点击屏幕时,从点击位置发出一条射线,使接触的 UI 交互组件正常响应点击。 Unity 的官方文档中有提及一共有三种射线发射器

这里有三种射线发射器

顺便一提,每次创建 UI 元素的时候都能看到它上面自带的组件中有个叫 Canvas Renderer 的,这个组件的官方解释是【附加到一个 Canvas 后,在完成所有正常渲染后将渲染到屏幕的组件。专为 GUI 应用程序设计。】

非常不起眼但有着重要作用的 Canvas Renderer

说实话我并没有看懂(这还是中文吗),但询问 claude 得到的答案是【Canvas Renderer 在 Canvas 的调度下,负责将单个 UI 元素最终渲染到屏幕上。Canvas 做的是统一管理和批处理,每个 UI 元素上的 Canvas Renderer 执行具体绘制。】那么这个问题就先到这里吧,接下来还是先回到原本的主题上

3,Rect Transform 链接到标题

Rect Transform 组件

这是调整 UI 元素最重要的组件之一,并且要注意 Anchor (锚点) 和 Pivot (轴心点) 的概念区分!!

Anchor 的参考对象是父物体的位置,Pivot 的参考对象是自己的位置,也就是说 Anchor 决定元素的定位对象,而 Pivot 决定元素自身用哪一个点去对齐这个位置。

锚点

锚点设置可以使用快捷键

直接点击的话锚点就会被置于以整个面板为基准的对应位置上

按住alt选择时能够快速将元素置于该元素内对应位置

按住shift选择可以快速将锚点置于该元素内对应位置

关于Anchor的拉伸模式:

当 Anchor Min ≠ Anchor Max 时,元素进入拉伸模式,此时 Rect Transform 中会从调整元素宽高变为调整元素边距值,这个边距值时相对于锚点的距离

可以通过调整 Min/Max Anchors来实现(不过通常来说,不是部分拉伸的话其实光是快捷键直接点击左上角选择对应拉伸效果就能解决了)

这里再和 Canvas Scaler 组件联系一下:Canvas Scaler 主要解决窗口的等比缩放,Anchor 拉伸解决元素再不同宽高比下的适配

4,万恶之源 Layout Group 们 链接到标题

因为 unity 的布局系统在调整过程中实在很容易出现各种问题,所以这里我把它们一起叫做万恶之源了(学习过程中,我的排版就是在各种调整之中突然莫名其妙被破坏,有时候得重开项目才能解决问题的,但是有一说一用熟练了之后应该还是比较好用的)

unity 中基本的 Layout Group组件大致分为三种:

网格布局
(子元素按行列网格排列)
水平布局
(子元素从左到右水平排列)
竖直布局
(子元素从上到下垂直排列)
Grid Layout Group Horizontal Layout Group Vertical Layout Group

三种不同布局拥有一些通用参数:

Grid Layout Group 和另外两种布局的区别比较大,在网格布局中每个子元素的大小都一致(这一点不受子元素上 LayoutElement 的影响),同时可以直接设置每一行/列的元素个数

而 Horizontal 和 Vertical 两种布局拥有另一些功能:

Reverse Arrangement 是反向排列元素

Control Child Size (控制子元素大小) , Use Child Scale (使用子元素缩放) 和 Child Force Expand (强制子元素扩展) 则是非常重要的三项功能

控制子元素大小通常使用于需要自动平分整个布局的场景,也就是希望每一项元素的宽/高度一致,比如像实现技能栏按钮平分宽度等等

使用子元素缩放使用的情况较少,但似乎会使用在动态缩放的图标列表中,或者调整使每个元素在布局中占用空间不同 (不过我并没有遇到使用这个功能的情况,这里就先不继续展开了)

强制子元素扩展需要子元素直接填充完整个布局的情况,会强制拉伸子元素,可配合 LayoutElement 控制子元素的拉伸,可以用此实现菜单收起之类的功能

顺便介绍一下经常和布局一起出现的好朋友 Content Size Fitter 组件:

顾名思义这个组件用于调整整个对象的大小, Unconstrained 就是默认不改变大小, Preferred Size 能让容器自动适应尺寸,考虑子元素的 Preferred Width/Height ,也是最常用的功能, Min Size 也是让容器自动适应尺寸,但只考虑子元素的 Min Width/Height ,使用情况较少,但是遇到需要缩小/折叠的窗口或者想要保证某些元素有最小可点击区域时可以采用这个。

一句话总结区别,就是 Preferred Size 更倾向于让容器适应子元素的"期望大小", Min Size更倾向于让容器适应子元素的"最小大小"

5,Layout Element 链接到标题

和上面的布局经常一起出现的第二个好朋友来了,虽然它在容器内的子元素中并不是必须的组件,但是当遇到需要精确控制某一个元素在布局中的表现时,就需要用到它了

Ignore Layout 可以使当前元素完全忽略容器的布局设置

Min Width/Height 就是该元素的最小尺寸,优先级最高

Preferred Width/Height 是该元素的理想尺寸

Flexible Width/Height 是弹性比例,用于分配容器中的剩余空间(比如假设现在容器内有三个元素,有一个弹性比例为1,有一个为2,最后一个为3,那么这三个元素分别得到的空间是容器的1/6,2/6和3/6),优先级最低

所以可以看出 Layout Group 分配空间的顺序:先保证元素的最小尺寸,如果有足够空间,给予元素期望尺寸,最后有多余空间时按比例扩展元素

6,比万恶之源还搞心态的 ScrollView 组件 链接到标题