# 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) - Scrollbar Vertical - Right_TaskDetails(右侧详情容器) - DetailText(TMP) ## 1. 总原则(先看这个,后面每一步都在用) 1) “左右两列”这类分屏 UI,外层用 `Horizontal Layout Group` 管分配;左右列用 `Layout Element` 提供宽度策略。 - 左列:固定宽(Preferred Width),不参与拉伸 - 右列:Flexible Width = 1,吃掉剩余空间 2) `ScrollRect` 必须正确引用: - `ScrollRect.Viewport` 指向 Viewport 的 RectTransform - `ScrollRect.Content` 指向 Viewport 下的 Content(列表根) 3) 列表项不要直接挂在 Viewport 下,而是挂在 Viewport/Content 下,由 `Vertical Layout Group` 统一排版。 4) 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:勾选 说明: - 你当前场景里 Content 的 `Child Control Width/Height` 是关闭的,这会导致左右两列“各管各的”,很难靠 LayoutGroup 统一管理边距与自适应。 ## 3. Left_TaskList(左列:固定宽 + 内部是滚动列表) 选中 `Content/Left_TaskList`: - 添加组件:`Layout Element` - Preferred Width:建议先用 `420`(按需求调) - Flexible Width:`0` - Min Width:可选(例如 `360`,防止过窄) - 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 下了),按下面步骤整理: 1) 选中 `Scroll View/Viewport`,把它的 RectTransform 改成全拉伸: - Anchor Presets:Stretch / Stretch - Left/Right/Top/Bottom:全部 0 2) 在 `Viewport` 下新建空物体命名为 `Content`(RectTransform): - Anchor: - Min `(0, 1)`,Max `(1, 1)`(X 拉伸,Y 顶部对齐) - Pivot:`(0.5, 1)` - Anchored Position:`(0, 0)` - Size Delta:`(0, 0)` 3) 给 `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` - `Content Size Fitter` - Horizontal Fit:Unconstrained - Vertical Fit:Preferred Size 4) 把你现在放在 `Viewport` 下的 `BtnTaskPrefab / BtnTaskPrefab 2 / ...` 全部移动到 `Viewport/Content` 下。 5) 回到 `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`(让父级控制) 这样列表项的高度稳定,不会因为文本变化导致整个 ScrollView 抖动。 ## 6. Right_TaskDetails(右列:吃剩余宽度) 选中 `Content/Right_TaskDetails`: - 添加组件:`Layout Element` - Flexible Width:`1` - Min Width:可选(例如 `600`,防止过窄) - RectTransform: - Anchor Presets:Stretch / Stretch 选中 `Right_TaskDetails/DetailText`: - RectTransform:Stretch / Stretch - Size Delta:用负值做内边距(例如 `(-50, -50)` 表示四边各留 25) - TMP: - Word Wrapping:开启 - Overflow:建议 `Overflow` 或 `Truncate`(按需求) ## 7. 常见问题排查(按出现频率排序) 1) Scroll View 不滚动 / 滚动条不动 - 先检查 `ScrollRect.Content` 是否为空(必须指向 `Viewport/Content`) - 再检查 `Viewport` 是否全拉伸(Offsets 是否为 0) 2) 左右列挤在一起、重叠、边距不生效 - 检查 `TaskPanelRoot/Content (Horizontal Layout Group)`: - `Child Control Width/Height` 是否勾上 - `Child Force Expand Width/Height` 是否勾上 - 检查左右列是否都有 `Layout Element`(左列 PreferredWidth,右列 FlexibleWidth=1) 3) 动态生成任务项后,布局不刷新 - 在列表根(`Viewport/Content`)挂 `LayoutGroupFix`,或在生成后手动触发一次 `LayoutRebuilder.ForceRebuildLayoutImmediate`