6.3 KiB
TaskSystem - UI 搭建与布局(UI_Test)
本文档用于把任务系统 UI 的布局调到“可维护 + 自适应分辨率 + 可扩展(动态生成任务项)”的状态。
目标场景:
Assets/_Project/Scenes/Test/UI_Test.unity
目标结构(最终建议形态):
- TaskPanelRoot(Image,可选;RectTransform:Stretch/Stretch,Offsets 全 0)
- Content(Horizontal Layout Group)
- Left_TaskList(用于承载 Scroll View 的“左列”)
- Scroll View
- Viewport(Mask)
- Content(Vertical Layout Group + Content Size Fitter)
- TaskItem(可复用 Prefab)
- Content(Vertical Layout Group + Content Size Fitter)
- Scrollbar Vertical
- Viewport(Mask)
- Scroll View
- Right_TaskDetails(右侧详情容器)
- DetailText(TMP)
- Left_TaskList(用于承载 Scroll View 的“左列”)
- Content(Horizontal Layout Group)
1. 总原则(先看这个,后面每一步都在用)
- “左右两列”这类分屏 UI,外层用
Horizontal Layout Group管分配;左右列用Layout Element提供宽度策略。
- 左列:固定宽(Preferred Width),不参与拉伸
- 右列:Flexible Width = 1,吃掉剩余空间
ScrollRect必须正确引用:
ScrollRect.Viewport指向 Viewport 的 RectTransformScrollRect.Content指向 Viewport 下的 Content(列表根)
-
列表项不要直接挂在 Viewport 下,而是挂在 Viewport/Content 下,由
Vertical Layout Group统一排版。 -
Reach Button 这类控件如果要放进 LayoutGroup 管理尺寸,优先把
ButtonManager.autoFitContent = false(让父级 LayoutGroup 控尺寸)。
2. TaskPanelRoot 与 Content(左右分屏容器)
在层级里选中 TaskPanelRoot:
- RectTransform:
- Anchor Presets:Stretch / Stretch
- Left/Right/Top/Bottom:全部 0
选中 TaskPanelRoot/Content(你场景里已有同名对象):
- 组件:
Horizontal Layout Group- Padding:建议先用
Left/Right/Top/Bottom = 40 - Spacing:
30 - Child Alignment:
Upper Left - Child Control Width:勾选
- Child Control Height:勾选
- Child Force Expand Width:勾选
- Child Force Expand Height:勾选
- Padding:建议先用
说明:
- 你当前场景里 Content 的
Child Control Width/Height是关闭的,这会导致左右两列“各管各的”,很难靠 LayoutGroup 统一管理边距与自适应。
3. Left_TaskList(左列:固定宽 + 内部是滚动列表)
选中 Content/Left_TaskList:
- 添加组件:
Layout Element- Preferred Width:建议先用
420(按需求调) - Flexible Width:
0 - Min Width:可选(例如
360,防止过窄)
- Preferred Width:建议先用
- RectTransform:
- Anchor Presets:Stretch / Stretch(至少 Y 方向要拉伸)
- Pos/Size:让 LayoutGroup 控制即可,不要再手调 anchoredPosition
说明:
- 你当前 Left_TaskList 是一个固定 SizeDelta(例如 350x730)并锚在左下角;如果想交给外层布局自适应,核心是加
Layout Element并让外层Horizontal Layout Group能控制子物体。
4. Scroll View(关键:Viewport 与 Content 的正确结构)
选中 Left_TaskList/Scroll View:
- 确认组件:
ScrollRect- Horizontal:关闭
- Vertical:开启
- Viewport:拖拽到
Viewport的 RectTransform - Content:拖拽到
Viewport/Content的 RectTransform - Vertical Scrollbar:拖拽到
Scrollbar Vertical
如果你的 Scroll View 里当前没有 Viewport/Content 这个对象(或者你把按钮直接放在 Viewport 下了),按下面步骤整理:
-
选中
Scroll View/Viewport,把它的 RectTransform 改成全拉伸:- Anchor Presets:Stretch / Stretch
- Left/Right/Top/Bottom:全部 0
-
在
Viewport下新建空物体命名为Content(RectTransform):- Anchor:
- Min
(0, 1),Max(1, 1)(X 拉伸,Y 顶部对齐)
- Min
- Pivot:
(0.5, 1) - Anchored Position:
(0, 0) - Size Delta:
(0, 0)
- Anchor:
-
给
Viewport/Content添加组件:Vertical Layout Group- Child Alignment:
Upper Left - Spacing:
12(按视觉调) - Child Control Width:勾选
- Child Control Height:勾选
- Child Force Expand Width:勾选
- Child Force Expand Height:取消(列表项高度通常固定,不希望被拉伸)
- Padding:建议
Left/Right/Top/Bottom = 10~20
- Child Alignment:
Content Size Fitter- Horizontal Fit:Unconstrained
- Vertical Fit:Preferred Size
-
把你现在放在
Viewport下的BtnTaskPrefab / BtnTaskPrefab 2 / ...全部移动到Viewport/Content下。 -
回到
Scroll View (ScrollRect):- 把
Content字段绑定到刚创建的Viewport/Content
- 把
可选兜底(动态生成任务项后,偶发排版不刷新时):
- 在
Viewport/Content上挂 Reach 的LayoutGroupFix(ThirdParty 内已有),并启用延迟 rebuild。
5. TaskItem(列表项 Prefab 的布局建议)
如果你复用 Reach Button 作为任务项:
ButtonManager.autoFitContent = false- 由父级
Vertical Layout Group决定宽度 - 在任务项根节点上添加
Layout Element:- Preferred Height:例如
56或64 - Flexible Width:
0(让父级控制)
- Preferred Height:例如
这样列表项的高度稳定,不会因为文本变化导致整个 ScrollView 抖动。
6. Right_TaskDetails(右列:吃剩余宽度)
选中 Content/Right_TaskDetails:
- 添加组件:
Layout Element- Flexible Width:
1 - Min Width:可选(例如
600,防止过窄)
- Flexible Width:
- RectTransform:
- Anchor Presets:Stretch / Stretch
选中 Right_TaskDetails/DetailText:
- RectTransform:Stretch / Stretch
- Size Delta:用负值做内边距(例如
(-50, -50)表示四边各留 25) - TMP:
- Word Wrapping:开启
- Overflow:建议
Overflow或Truncate(按需求)
7. 常见问题排查(按出现频率排序)
- Scroll View 不滚动 / 滚动条不动
- 先检查
ScrollRect.Content是否为空(必须指向Viewport/Content) - 再检查
Viewport是否全拉伸(Offsets 是否为 0)
- 左右列挤在一起、重叠、边距不生效
- 检查
TaskPanelRoot/Content (Horizontal Layout Group):Child Control Width/Height是否勾上Child Force Expand Width/Height是否勾上
- 检查左右列是否都有
Layout Element(左列 PreferredWidth,右列 FlexibleWidth=1)
- 动态生成任务项后,布局不刷新
- 在列表根(
Viewport/Content)挂LayoutGroupFix,或在生成后手动触发一次LayoutRebuilder.ForceRebuildLayoutImmediate