12 KiB
75 · 菜单布局与操作逻辑对照 + 改造方案
目标:将暂停 / 背包 / 地图 / 护符 / 能力等游戏内菜单的组成布局逻辑与打开-关闭-切换操作逻辑,对齐业界横版动作冒险标杆作的交互范式,同时保留本项目独有玩法(三形态切换、形态下的魂技能 / 魄技能、无"工具(Tools)"系统)。
本文档只定义信息架构与交互契约,不照搬任何标杆作的玩法系统。 命名 / 目录 / Addressable / Layer 一律遵守
Docs/Standards/;所有搭建走Assets/_Game/Scripts/Editor脚手架,不裸建。
相关文档:Docs/Design/10_UISystem.md、Docs/Design/74_UIScreenFlowDocument.md、Docs/Design/16_MapSystem.md、Docs/DesignSpec/06_FormSystem.md、Docs/DesignSpec/10_UISystem.md。
0. 一句话结论
架构已到位(统一导航栈、L/R 切 Tab、暗雾地图、确认弹窗、数据驱动配置都有)。差距在信息架构:当前存在"暂停按钮菜单"与"背包 Tab Hub"两条并行入口、内容重叠;目标是把游戏内一切查看/装备类面板收敛进统一 Tab 屏,暂停退化为薄覆盖层。再补一个缺失的图鉴面板。本质是收敛接线 + 补面板,新代码很少。
1. 对标范围界定
| 维度 | 是否参考标杆 | 说明 |
|---|---|---|
| 菜单布局结构(Tab 划分、层级) | ✅ 参考 | 一键进入带 Tab 的统一屏 |
| 操作逻辑(开/关/切 Tab/回退/焦点) | ✅ 参考 | 同键开关、L/R 切页、B 逐层退、手柄全程可达 |
| 地图面板形态 | ✅ 完全参考 | 暗雾、Pin、传送、缩放居中 |
| 玩法系统(护符/工具/资源) | ❌ 用本项目自有 | 无 Tools;护符保持现有凹槽模型;资源为灵力/魄元而非"丝/念珠" |
| 技能呈现 | ➖ 本项目原创 | 三形态 × 魂技能/魄技能,标杆作无此概念,作为独立 Tab 承载 |
2. 当前实现现状(事实基线)
2.1 两条入口
| 入口 | 触发链 | 落点 |
|---|---|---|
| 暂停 | Gameplay Pause Action → EVT_PauseRequested → UIManager.TogglePause() → OpenPanel(PanelId.Pause) |
DataDrivenPauseMenuController(竖排按钮,数据驱动) |
| 背包 | Gameplay Inventory Action → EVT_InventoryOpen → OpenPanel(PanelId.Inventory) |
InventoryHubPanel(Tab Hub,L/R 肩键切页) |
| 地图(独立) | EVT_MapOpen / EVT_FastTravelOpen → OpenPanel(PanelId.Map) |
MapPanel(独立面板,不在 Hub 内) |
| 护符(独立) | EVT_CharmPanelOpen → OpenPanel(PanelId.CharmPanel) |
CharmEquipPanel(独立面板) |
问题:暂停菜单的按钮可用 PauseMenuAction.OpenPanel 跳 FormSkills / Abilities / Map;而这些又能作为 Hub 的 Tab。同一内容两套入口、两种布局,是与标杆范式最大的结构偏差。
2.2 已有面板与 PanelId
PanelId(UIManager.cs):Pause, Settings, Map, Shop, CharmPanel, SpellSelect, Inventory, FormSkills, Abilities。
| 面板 | 脚本 | 现状 |
|---|---|---|
| 暂停 | Menus/DataDrivenPauseMenuController.cs |
✅ 数据驱动 |
| 背包 Hub | Inventory/InventoryHubPanel.cs |
✅ Tab 容器(注释规划 Map/Inventory/Tools/Journal/Quests/Options) |
| 物品 | Inventory/ItemInventoryPanel.cs |
✅ 网格+详情(仅展示) |
| 任务 | Inventory/QuestLogPanel.cs |
✅ 存在 |
| 护符 | CharmEquipPanel.cs + CharmCardView.cs |
✅ 凹槽装备 |
| 地图 | World/Map/MapPanel.cs |
✅ 暗雾/Pin/传送/定位器门控 |
| 形态技能 | FormSkillPanel.cs |
✅ 三形态 × 魂/魄(只读) |
| 能力总览 | DataDrivenAbilityPanel.cs + AbilityCellView.cs |
✅ 数据驱动解锁态 |
| 设置 | Settings/DataDrivenSettingsPanel.cs |
✅ 数据驱动 |
| 图鉴(Bestiary) | — | ❌ 缺失 |
2.3 已具备的操作逻辑(无需重做)
- 统一导航栈
UINavigator:Push/Pop、焦点保存恢复、Modal 屏蔽下层、场景卸载清栈。 - 取消归口:UI map
Cancel(ESC / 手柄 B)→EVT_UICancelPressed→ 导航器关栈顶一层。 - Tab 切换:
InventoryHubPanel监听EVT_InventoryTabNext/Prev(UI map 肩键)+ 头部按钮点击;焦点委托给 Tab 内容(若实现IFocusable)。 - 地图专用键:
CycleMinimapZoom、MapCenter。
3. 标杆范式要点(交互参考,去玩法)
- 单键进统一屏:一个键打开带横向 Tab 的菜单屏;同键再按关闭(toggle)。
- L/R 肩键循环 Tab,Tab 头显示名称 + 肩键提示字形(随输入设备切换 KB/手柄图标)。
- 地图可独立直达:地图键直接打开"统一屏并定位到地图 Tab"。
- B/Circle/ESC 逐层回退:先关子详情,再关整屏。
- 暂停是薄覆盖:游戏冻结、半透明,仅 Resume / Options / Return / Quit,不承载查看类面板。
- 手柄全程可达:每个 Tab/列表进入即有默认焦点。
4. 逐项对照(符合度)
| 范式要点 | 当前 | 符合度 | 差距 |
|---|---|---|---|
| 单键进统一 Tab 屏 | 有 Hub,但内容也散落在暂停菜单 | ⚠️ 部分 | 入口重叠,需收敛 |
| 同键 toggle 关闭 | OpenInventory 只 Push 不 toggle |
⚠️ 部分 | 缺再按关闭 |
| L/R 切 Tab + 头部字形提示 | L/R 已有;字形提示未确认 | ⚠️ 部分 | Tab 头补设备图标提示 |
| 地图键直达地图 Tab | 地图是独立面板,与 Hub 并行 | ❌ 不符 | 地图应作为 Tab;地图键打开 Hub 并选中地图 Tab |
| B/ESC 逐层回退 | UINavigator 已实现 |
✅ 符合 | — |
| 暂停薄覆盖、不含查看面板 | 暂停菜单含 OpenPanel 跳转项 |
❌ 不符 | 移除跳转项,仅留系统操作 |
| 手柄全程焦点 | 基类已支持,逐面板需核 | ⚠️ 部分 | 各 Tab 内容补 IFocusable |
| 护符/装备 | 凹槽模型(本项目自有) | ✅ 按本项目算符合 | 仅作 Tab 收编 |
| 形态技能(魂/魄) | 独立面板(本项目自有) | ✅ 符合 | 作 Tab 收编 |
| 地图形态 | 暗雾/Pin/传送/定位器门控 | ✅ 高度符合 | 仅缺快旅历史(可选) |
| 图鉴 Bestiary | 无 | ❌ 缺失 | 新建面板 + Tab |
5. 目标信息架构
5.1 统一 Tab 屏(InventoryHubPanel,PanelId.Inventory)
Tab 顺序(结合本项目内容,"工具"位由"形态技能"承载):
| # | Tab | 承载面板 | 备注 |
|---|---|---|---|
| 1 | 地图 | MapPanel |
由独立面板收编为 Tab;地图键直达此 Tab |
| 2 | 形态技能 | FormSkillPanel |
三形态 × 魂/魄(本项目核心,取代标杆"工具"位) |
| 3 | 能力 | DataDrivenAbilityPanel |
解锁总览 |
| 4 | 护符 | CharmEquipPanel |
凹槽装备(收编为 Tab) |
| 5 | 物品 | ItemInventoryPanel |
收藏/材料/关键道具 |
| 6 | 任务 | QuestLogPanel |
NPC 任务日志 |
| 7 | 图鉴 | BestiaryPanel(新建) |
击杀解锁敌人条目 |
Tab 数量可裁剪;至少 1/2/4/5 为首发必备,3/6/7 视进度排期。
5.2 暂停薄覆盖(DataDrivenPauseMenuController,PanelId.Pause)
仅保留系统级动作,删除一切 OpenPanel 查看类跳转:
| 项 | Action |
|---|---|
| 继续 | Resume |
| 选项 | OpenSettings |
| 返回主菜单 | ReturnToMainMenu |
| 退出 | Quit |
5.3 入口操作契约
| 输入 | 行为 |
|---|---|
Inventory 键 |
打开统一屏(回上次 Tab);已开则关闭(toggle) |
地图键(EVT_MapOpen/EVT_FastTravelOpen) |
打开统一屏并选中地图 Tab |
InventoryTabNext/Prev(L/R 肩键) |
在统一屏内循环 Tab |
Pause 键(Start) |
打开暂停薄覆盖(独立,不与统一屏共栈语义) |
Cancel(ESC/B) |
导航器关栈顶一层(子详情→整屏) |
6. 改造方案(分阶段)
全程走脚手架;改完跑第 8 节验证。
阶段 A — 收敛入口职责(低风险,主要是配置)
- 精简暂停配置
Assets/_Game/Data/UI/UI_PauseMenuConfig.asset:删除FormSkills/Abilities/Map等OpenPanel项,仅留 Resume/Settings/ReturnToMainMenu/Quit。 - 背包键 toggle:在
UIManager为OpenInventory()增加 toggle(参照现有TogglePause()模式:栈顶若为 Inventory 则Pop,否则OpenPanel)。 - 地图键直达地图 Tab:将
EVT_MapOpen/EVT_FastTravelOpen改为"打开 Inventory Hub 并选中地图 Tab"。建议给InventoryHubPanel增OpenAtTab(int)/ 增一个IntEventChannelSO(如EVT_InventoryOpenAtTab),UIManager.OpenMap()打开 Hub 后请求选中地图 Tab。- 保留
MapPanel独立 PanelId 与否由"地图是否需脱离 Hub 全屏"决定(见第 9 节待决)。
- 保留
阶段 B — 面板收编为 Tab(用脚手架重建 Hub 预制件)
- 扩建
UI_InventoryHub预制件:用InventoryHubScaffoldWizard.ScaffoldInventoryHub(或现有 Hub 脚手架)把 5.1 的面板逐个挂为TabEntry.content,配headerButton+headerHighlight,按 5.1 顺序排列。- 各 Tab 内容根需实现
IFocusable(或保证内部首项可聚焦),以便切 Tab 自动接管焦点。 - 地图 / 护符既有独立 PanelId 的,改为实例复用:要么 Tab 内嵌同一面板预制,要么 Hub 内 Tab 与独立 PanelId 指向同一 root(二选一,避免双实例,见待决)。
- 各 Tab 内容根需实现
- Tab 头字形提示:Tab 条左右加
InputIconImage/InputDeviceIconSwitcher,显示 L/R 肩键字形(随设备切换)。
阶段 C — 补图鉴(新面板)
- 新建
BestiaryPanel:仿DataDrivenAbilityPanel的数据驱动套路——BestiaryEntrySO/数据库 SO 列敌人条目,击杀解锁(订阅敌人死亡事件),网格 + 详情。先补对应 Editor 脚手架(参考UIAbilityOverviewScaffold的AssignReference绑定模式)再建预制件。 - 注册为第 7 个 Tab;数据源接
Docs/Design/48_EnemyRoster.md/ 敌人数据库。
阶段 D — 打磨
- 进出场动画统一(Hub 已有滑入+淡入);暂停覆盖层半透明背板。
- 逐 Tab 核手柄默认焦点;确认
Cancel在"子详情打开时只退一层"。
7. 涉及改动清单(速查)
| 类型 | 对象 | 改动 |
|---|---|---|
| 资产 | UI_PauseMenuConfig.asset |
删跳转项 |
| 代码 | UIManager.cs |
OpenInventory toggle;OpenMap 改为开 Hub 定位地图 Tab |
| 代码 | InventoryHubPanel.cs |
增 OpenAtTab(int) + 监听 EVT_InventoryOpenAtTab |
| 事件 | 新增 EVT_InventoryOpenAtTab(Int) |
经 CreateEventChannelAssets 创建 |
| 预制件 | UI_InventoryHub |
经 Hub 脚手架挂全部 Tab + 字形提示 |
| 新建 | BestiaryPanel + SO + 脚手架 + 预制件 |
阶段 C |
| 可选 | PanelId.Bestiary |
若图鉴也需独立直达 |
8. 改造后自检(强制)
BaseGames/Tools/Validation/Validate All ScriptableObjectsBaseGames/Addressables/Validate Address Keys(新 SO/预制件地址常量化)BaseGames/Tools/Maintenance/Physics2D Layer Matrix/Check- 运行期手测:背包键 toggle、L/R 切 7 个 Tab、地图键直达地图 Tab、暂停覆盖仅系统项、ESC 逐层退、全程手柄可达。
9. 待决问题
- 地图双形态:地图既作 Hub 的 Tab,又是否保留可全屏脱离 Hub 的独立打开?(影响是否保留
PanelId.Map双实例策略) - 首发 Tab 集:7 个是否全部首发,还是先上 地图/形态技能/护符/物品,能力·任务·图鉴二期?
- 图鉴数据源:解锁条件(首次击杀?需击杀 N 次解锁全条目?)与数据归属(敌人数据库 vs 独立
BestiaryEntrySO)。 - 暂停与统一屏的栈关系:是否允许在暂停覆盖里再开统一屏(一般不允许,二者互斥)。