Skip to main content
摘要:本文聚焦「Unity RectTransform 深度解析」,梳理核心概念、关键方法与落地实践。
RectTransform 是 Unity UGUI 系统的核心组件,继承自 Transform。虽然它保留了位置、旋转和缩放属性,但其定位逻辑与普通 3D 物体截然不同。 很多开发者在处理 UI 适配(分辨率变化)时感到痛苦,根源往往是对 Anchors(锚点)Pivot(轴心)SizeDelta 的数学定义理解不深。

1. 核心概念图解

1.1 Pivot (轴心) —— 自身的原点

  • 定义: UI 元素自身的“中心点”,坐标范围通常是 (0,0) 到 (1,1)。
    • (0.5, 0.5): 正中心。
    • (0, 1): 左上角。
  • 作用:
    1. 旋转中心: 物体绕着 Pivot 旋转。
    2. 坐标原点: transform.position 指的就是 Pivot 在世界空间的位置。
    3. 缩放中心: 物体向着 Pivot 收缩。

1.2 Anchors (锚点) —— 父级的参考系

  • 定义: 由 4 个三角形组成(Inspector 中显示为 Min X, Min Y, Max X, Max Y)。
  • 本质: 定义了该 UI 元素相对于父级矩形的哪一部分进行定位。
  • 坐标系: 归一化坐标 (0~1),相对于父级的宽高。
    • Min(0,0) Max(0,0): 锚定在父级左下角。
    • Min(1,1) Max(1,1): 锚定在父级右上角。
    • Min(0,0) Max(1,1): 完全拉伸 (Stretch),锚点框住整个父级。

2. 两种形态:点模式 vs 拉伸模式

理解 RectTransform 最关键的一点是:根据 Anchors 是否重合,属性面板显示的变量含义会完全改变!

2.1 点模式 (Anchors 重合)

Anchor Min 等于 Anchor Max 时(例如都在中心),锚点是一个
  • PosX / PosY / PosZ: Pivot 相对于 Anchor Point 的距离。
  • Width / Height: 元素的固定宽和高(绝对像素值)。
  • 行为: 父级变大时,该元素大小不变,位置随锚点移动。

2.2 拉伸模式 (Anchors 分离)

Anchor Min 不等于 Anchor Max 时(例如 Min(0,0) Max(1,0) 底边拉伸),锚点形成一个矩形区域
  • Left / Top / Right / Bottom: 元素边缘距离 Anchors 矩形边缘 的距离(Padding)。
    • 这不再是 PosX/Y,而是类似 CSS 的 margin。
  • Width / Height 消失了! 变成了无法直接设置的值(由父级决定)。
  • 行为: 父级变大时,该元素会随之拉伸。

3. 属性黑盒:SizeDelta 与 Offset

这是代码控制 UI 时最大的坑。

3.1 sizeDelta 的真相

很多人以为 rectTransform.sizeDelta 就是宽高。大错特错! sizeDelta=ElementSizeAnchorSizesizeDelta = \text{ElementSize} - \text{AnchorSize}
  • 在点模式下: AnchorSize 为 0,所以 sizeDelta 等于 宽高。
  • 在拉伸模式下: sizeDelta 代表相对于锚点的距离差
    • 如果全屏拉伸 (Stretch All),sizeDelta 为 (0,0) 时,代表填满父级。
    • 此时设置 sizeDelta 为 (100, 100),意味着比父级 100像素!(负边距)。

3.2 offsetMinoffsetMax

这两个属性是通用的,无论什么模式都能用。
  • offsetMin: 对应 (Left, Bottom) 的角相对于锚点的位移。
  • offsetMax: 对应 (Right, Top) 的角相对于锚点的位移。
实战技巧:代码设置全屏拉伸

4. 坐标系转换神器:RectTransformUtility

不要自己算坐标!不要自己算坐标!不要自己算坐标! Unity 提供了 RectTransformUtility 处理复杂的 Pivot 和 Canvas 缩放。

4.1 为什么需要 Camera 参数?

  • Overlay Canvas: 不需要 Camera(传 null),因为 UI 直接渲染在屏幕上。
  • Camera Canvas: 需要传入渲染该 Canvas 的摄像机 (canvas.worldCamera),因为此时 UI 是 3D 世界的一部分,受透视影响。

5. 常见实战案例 (Cookbook)

5.1 案例 A: UI 元素始终位于屏幕右上角

  • 编辑器设置:
    • Anchors: Min(1,1), Max(1,1) (右上角点模式)
    • Pivot: (1, 1) (自身的右上角)
    • Pos: (0, 0)
  • 原理解析:
    • 锚点定在父级右上角。
    • 自身轴心在右上角。
    • 位置偏移为0。
    • 结果:元素的右上角与父级右上角重合。

5.2 案例 B: 制作一个血条 (跟随 3D 物体)

这是一个极其高频的需求。

5.3 案例 C: 异形屏适配 (Safe Area)

处理 iPhone 刘海屏或挖孔屏。

5.4 案例 D: 终极挑战——跨 Canvas 坐标同步

将一个 UI 元素(如物品栏里的图标)从 Canvas A 移动到 Canvas B,或者让 Canvas B 里的特效跟随 Canvas A 里的按钮。 难点:
  • Canvas A 可能是 Screen Space - Overlay (无 Camera)。
  • Canvas B 可能是 Screen Space - Camera (有 Camera, 且距离不同)。
  • 两者的 Scale Factor 可能不同。
通用解决方案: 使用 屏幕坐标 (Screen Space) 作为绝对中介。

6. 性能优化 (Performance)

RectTransform 的变动(Re-layout)是非常昂贵的,它会触发布局系统的重建。
  1. Canvas 分层:
    • 动态元素(如血条、倒计时)和静态元素(如背景板、固定图标)放在不同的 Canvas (或 Sub-Canvas) 中。
    • 当一个 UI 元素变动时,同一个 Canvas 下的所有元素都可能需要重新生成网格。
  2. 少用 LayoutGroup:
    • VerticalLayoutGroup, GridLayoutGroup 等自动布局组件性能开销大。
    • 如果是列表,务必使用 对象池 (Object Pooling) + 无限滚动 (Infinite Scroll),而不是实例化 100 个 Item。
  3. Pixel Perfect:
    • Canvas 上的 Pixel Perfect 选项会增加计算量,非像素风游戏通常不需要开启。

7. 速查表:我该用哪个属性?