Unity 的 Horizontal Layout Group(水平布局组)主要用于:让多个 UI 子物体沿水平方向自动排列,并根据子物体尺寸、父节点尺寸和布局参数自动计算位置/尺寸。
它通常和 Vertical Layout Group、Content Size Fitter、Layout Element 配合使用。
下面按 Inspector 参数逐个讲。
1. Horizontal Layout Group
4
假设层级是:
Panel
└── Horizontal Layout Group
├── Item A
├── Item B
└── Item C
它会负责:
| Padding | A | Spacing | B | Spacing | C | Padding |
2. Padding
Padding
Left
Right
Top
Bottom
控制子物体距离父物体边缘的内边距。
例如:
Panel
┌──────────────────────────────┐
│ ← Left │
│ ┌────┐ ┌────┐ ┌────┐ │
│ │ A │ │ B │ │ C │ │
│ └────┘ └────┘ └────┘ │
│ → Right│
└──────────────────────────────┘
如果:
Left = 20
Right = 20
Top = 10
Bottom = 10
那么子物体布局区域会变成:
父节点宽度
↓
| 20 |---------- 子物体区域 ----------| 20 |
重点
Padding 是父节点内部的边距。
不是子物体之间的间距。
3. Spacing
Spacing = 10
控制子物体之间的水平间距。
例如:
A B C
┌───┐ ┌───┐ ┌───┐
│ A │ │ B │ │ C │
└───┘ └───┘ └───┘
↑ ↑
10px 10px
公式可以简单理解成:
A宽度 + Spacing + B宽度 + Spacing + C宽度
4. Child Alignment
这个参数非常重要。
它决定:
当所有子物体没有把父节点空间占满时,整体放在哪里。
常见选项:
Upper Left
Upper Center
Upper Right
Middle Left
Middle Center
Middle Right
Lower Left
Lower Center
Lower Right
对于 Horizontal Layout Group,最常用的是:
Middle Left
Middle Center
Middle Right
例如:
Middle Left
┌──────────────────────────────┐
│ │
│ A B C │
│ │
└──────────────────────────────┘
Middle Center
┌──────────────────────────────┐
│ │
│ A B C │
│ │
└──────────────────────────────┘
Middle Right
┌──────────────────────────────┐
│ │
│ A B C │
│ │
└──────────────────────────────┘
注意:
Child Alignment 不是控制子物体之间的排列方式。
它主要是在:
布局空间 > 子物体实际占用空间
的时候决定剩余空间放哪边。
5. Control Child Size
这是 Horizontal Layout Group 最容易搞混的参数。
Control Child Size
Width
Height
意思是:
是否由 Horizontal Layout Group 控制子物体的宽度/高度。
Width
Width = ❌
Control Child Size
Width ❌
意味着:
Horizontal Layout Group 不强制修改子物体的宽度。
例如:
A = 100
B = 200
C = 150
布局组会尽量保持这些宽度。
Width = ✅
Width ✅
意味着:
Horizontal Layout Group 会参与决定子物体的宽度。
但这里有一个非常重要的点:
它不等于“所有子物体一样宽”。
最终宽度还会受到:
Child Force Expand
Layout Element
Min Width
Preferred Width
Flexible Width
等参数影响。
6. Control Child Size Height
Height
如果:
Height ❌
那么 Layout Group 不会主动控制子物体高度。
例如:
A = 50
B = 100
C = 70
可能保持:
┌────┐
│ A │
└────┘
┌────┐
│ B │
│ │
└────┘
┌────┐
│ C │
└────┘
如果:
Height ✅
Horizontal Layout Group 会参与计算子物体高度。
如果同时:
Child Force Expand
Height ✅
那么通常会出现:
┌────────────────────┐
│ │
│ A │
│ │
├────────────────────┤
│ B │
│ │
├────────────────────┤
│ C │
│ │
└────────────────────┘
子物体可能被拉伸到布局区域高度。
7. Use Child Scale
Use Child Scale
Width
Height
这个参数相对少用。
它决定:
布局计算时是否考虑子物体的 Transform.localScale。
例如:
Child
Width = 100
Scale X = 2
如果:
Use Child Scale Width ❌
布局系统可能按照:
100
参与计算。
如果:
Use Child Scale Width ✅
则布局计算会考虑:
100 × 2 = 200
为什么一般不推荐依赖它?
UI 中通常更推荐:
RectTransform
+
Layout Element
来控制布局尺寸,而不是:
Transform.localScale
尤其是复杂 UI。
8. Child Force Expand
这是另一个非常重要的参数。
Child Force Expand
Width
Height
它的含义是:
如果父节点还有多余空间,是否强制让子物体扩展去占用这些空间。
Width = ❌
假设:
Panel Width = 500
A = 100
B = 100
C = 100
Spacing = 10
实际需要:
100 + 10 + 100 + 10 + 100
= 320
还有:
500 - 320 = 180
剩余空间。
如果:
Child Force Expand Width ❌
那么不会自动把 180 分给 A/B/C。
结果类似:
┌─────────────────────────────────────┐
│ A B C │
└─────────────────────────────────────┘
然后由:
Child Alignment
决定它们靠左、居中还是靠右。
Width = ✅
如果:
Child Force Expand Width ✅
那么:
A B C
会尝试利用额外空间。
例如:
┌─────────────────────────────────────┐
│ A B C │
└─────────────────────────────────────┘
每个子物体可能被扩展。
9. Child Force Expand 和 Control Child Size 的区别
这是最容易混淆的一组。
可以这样记:
Control Child Size
“我管不管你的尺寸?”
Child Force Expand
“有多余空间,我要不要让你扩张?”
例如:
Control Child Size Width = ❌
Child Force Expand Width = ❌
布局组:
你的宽度我不管,也不给你额外宽度。
Control Child Size Width = ✅
Child Force Expand Width = ❌
布局组:
你的宽度我会参与计算,但有多余空间时不强制扩张。
Control Child Size Width = ✅
Child Force Expand Width = ✅
布局组:
你的宽度我参与计算,而且有剩余空间就让你扩张。
10. Layout Element 才是关键
实际开发中,Horizontal Layout Group 往往会和:
Layout Element
一起使用。
例如:
Panel
└── Horizontal Layout Group
├── Button A + Layout Element
├── Button B + Layout Element
└── Button C + Layout Element
Layout Element 中常见:
Min Width
Min Height
Preferred Width
Preferred Height
Flexible Width
Flexible Height
这几个参数决定了子物体在布局系统中的“需求”。
11. Min / Preferred / Flexible 怎么理解
可以把它理解成:
Min = 最小尺寸
Preferred = 我希望有这么大
Flexible = 如果还有空间,我还能吃多少
例如一个 Item:
Min Width = 50
Preferred Width = 100
Flexible Width = 1
可以理解成:
最少给我 50,正常希望给我 100,如果还有多余空间,我愿意继续扩张。
12. 一个非常典型的 UI 案例
例如做一个:
[头像] [玩家名字] [金币 9999]
层级:
PlayerInfo
└── Horizontal Layout Group
├── Avatar
├── Name
└── Gold
希望:
┌──────────────────────────────────────┐
│ 👤 PlayerName 💰9999│
└──────────────────────────────────────┘
这种需求不能简单靠:
Spacing
解决。
通常会使用:
PlayerInfo
Horizontal Layout Group
Avatar
Layout Element
Name
Layout Element
Flexible Width = 1
Gold
Layout Element
这样:
Avatar 固定
Name 吃掉中间剩余空间
Gold 固定
最终:
| Avatar | Name | Gold |
这就是 Flexible Width 很典型的用途。
13. Horizontal Layout Group 参数总结
| 参数 | 作用 |
|---|---|
| Padding | 父节点内部边距 |
| Spacing | 子物体之间的间距 |
| Child Alignment | 子物体整体在剩余空间中的对齐方式 |
| Control Child Size Width | 是否控制子物体宽度 |
| Control Child Size Height | 是否控制子物体高度 |
| Use Child Scale Width | 布局计算是否考虑子物体 X Scale |
| Use Child Scale Height | 布局计算是否考虑子物体 Y Scale |
| Child Force Expand Width | 是否强制利用剩余水平空间 |
| Child Force Expand Height | 是否强制利用剩余垂直空间 |
14. 最重要的理解:Layout Group 到底怎么算?
你可以把 Horizontal Layout Group 简化理解成这个流程:
① Padding
↓
确定可用区域
② 子物体 Min / Preferred / Flexible
↓
计算每个 Child 应该多宽
③ Spacing
↓
计算 Child 之间间距
④ Child Force Expand
↓
处理剩余空间
⑤ Child Alignment
↓
处理最终剩余空间的位置
⑥ 设置 Child RectTransform
↓
最终 UI
所以遇到:
“为什么我的 Button 明明设置 Width=100,Horizontal Layout Group 却变成 200?”
不要只看 Button 的 RectTransform Width。
应该一路检查:
Horizontal Layout Group
↓
Control Child Size
↓
Child Force Expand
↓
Layout Element
↓
Min / Preferred / Flexible
尤其是 Layout Element + Flexible Width,是 Unity UI 自动布局里非常核心的一套机制。