Files
zeling_v2/Docs/Design/75_MenuLayoutRemodelPlan.md
2026-06-08 11:26:17 +08:00

12 KiB
Raw Blame History

75 · 菜单布局与操作逻辑对照 + 改造方案

目标:将暂停 / 背包 / 地图 / 护符 / 能力等游戏内菜单的组成布局逻辑打开-关闭-切换操作逻辑,对齐业界横版动作冒险标杆作的交互范式,同时保留本项目独有玩法(三形态切换、形态下的魂技能 / 魄技能、无"工具(Tools)"系统)。

本文档只定义信息架构与交互契约,不照搬任何标杆作的玩法系统。 命名 / 目录 / Addressable / Layer 一律遵守 Docs/Standards/;所有搭建走 Assets/_Game/Scripts/Editor 脚手架,不裸建。

相关文档:Docs/Design/10_UISystem.mdDocs/Design/74_UIScreenFlowDocument.mdDocs/Design/16_MapSystem.mdDocs/DesignSpec/06_FormSystem.mdDocs/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_PauseRequestedUIManager.TogglePause()OpenPanel(PanelId.Pause) DataDrivenPauseMenuController(竖排按钮,数据驱动)
背包 Gameplay Inventory Action → EVT_InventoryOpenOpenPanel(PanelId.Inventory) InventoryHubPanelTab HubL/R 肩键切页)
地图(独立) EVT_MapOpen / EVT_FastTravelOpenOpenPanel(PanelId.Map) MapPanel(独立面板,不在 Hub 内
护符(独立) EVT_CharmPanelOpenOpenPanel(PanelId.CharmPanel) CharmEquipPanel(独立面板)

问题:暂停菜单的按钮可用 PauseMenuAction.OpenPanelFormSkills / Abilities / Map;而这些又能作为 Hub 的 Tab。同一内容两套入口、两种布局,是与标杆范式最大的结构偏差。

2.2 已有面板与 PanelId

PanelIdUIManager.csPause, 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 已具备的操作逻辑(无需重做)

  • 统一导航栈 UINavigatorPush/Pop、焦点保存恢复、Modal 屏蔽下层、场景卸载清栈。
  • 取消归口UI map CancelESC / 手柄 BEVT_UICancelPressed → 导航器关栈顶一层。
  • Tab 切换:InventoryHubPanel 监听 EVT_InventoryTabNext/PrevUI map 肩键)+ 头部按钮点击;焦点委托给 Tab 内容(若实现 IFocusable)。
  • 地图专用键:CycleMinimapZoomMapCenter

3. 标杆范式要点(交互参考,去玩法)

  1. 单键进统一屏:一个键打开带横向 Tab 的菜单屏同键再按关闭toggle
  2. L/R 肩键循环 TabTab 头显示名称 + 肩键提示字形(随输入设备切换 KB/手柄图标)。
  3. 地图可独立直达:地图键直接打开"统一屏并定位到地图 Tab"。
  4. B/Circle/ESC 逐层回退:先关子详情,再关整屏。
  5. 暂停是薄覆盖:游戏冻结、半透明,仅 Resume / Options / Return / Quit不承载查看类面板
  6. 手柄全程可达:每个 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 屏(InventoryHubPanelPanelId.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 暂停薄覆盖(DataDrivenPauseMenuControllerPanelId.Pause

仅保留系统级动作,删除一切 OpenPanel 查看类跳转

Action
继续 Resume
选项 OpenSettings
返回主菜单 ReturnToMainMenu
退出 Quit

5.3 入口操作契约

输入 行为
Inventory 打开统一屏(回上次 Tab已开则关闭toggle
地图键(EVT_MapOpen/EVT_FastTravelOpen 打开统一屏并选中地图 Tab
InventoryTabNext/PrevL/R 肩键) 在统一屏内循环 Tab
PauseStart 打开暂停薄覆盖(独立,不与统一屏共栈语义)
CancelESC/B 导航器关栈顶一层(子详情→整屏)

6. 改造方案(分阶段)

全程走脚手架;改完跑第 8 节验证。

阶段 A — 收敛入口职责(低风险,主要是配置)

  1. 精简暂停配置 Assets/_Game/Data/UI/UI_PauseMenuConfig.asset:删除 FormSkills/Abilities/MapOpenPanel 项,仅留 Resume/Settings/ReturnToMainMenu/Quit。
  2. 背包键 toggle:在 UIManagerOpenInventory() 增加 toggle参照现有 TogglePause() 模式:栈顶若为 Inventory 则 Pop,否则 OpenPanel)。
  3. 地图键直达地图 Tab:将 EVT_MapOpen/EVT_FastTravelOpen 改为"打开 Inventory Hub 并选中地图 Tab"。建议给 InventoryHubPanelOpenAtTab(int) / 增一个 IntEventChannelSO(如 EVT_InventoryOpenAtTabUIManager.OpenMap() 打开 Hub 后请求选中地图 Tab。
    • 保留 MapPanel 独立 PanelId 与否由"地图是否需脱离 Hub 全屏"决定(见第 9 节待决)。

阶段 B — 面板收编为 Tab用脚手架重建 Hub 预制件)

  1. 扩建 UI_InventoryHub 预制件:用 InventoryHubScaffoldWizard.ScaffoldInventoryHub(或现有 Hub 脚手架)把 5.1 的面板逐个挂为 TabEntry.content,配 headerButton + headerHighlight,按 5.1 顺序排列。
    • 各 Tab 内容根需实现 IFocusable(或保证内部首项可聚焦),以便切 Tab 自动接管焦点。
    • 地图 / 护符既有独立 PanelId 的,改为实例复用:要么 Tab 内嵌同一面板预制,要么 Hub 内 Tab 与独立 PanelId 指向同一 root二选一避免双实例见待决
  2. Tab 头字形提示Tab 条左右加 InputIconImage / InputDeviceIconSwitcher,显示 L/R 肩键字形(随设备切换)。

阶段 C — 补图鉴(新面板)

  1. 新建 BestiaryPanel:仿 DataDrivenAbilityPanel 的数据驱动套路——BestiaryEntrySO/数据库 SO 列敌人条目,击杀解锁(订阅敌人死亡事件),网格 + 详情。先补对应 Editor 脚手架(参考 UIAbilityOverviewScaffoldAssignReference 绑定模式)再建预制件。
  2. 注册为第 7 个 Tab数据源接 Docs/Design/48_EnemyRoster.md / 敌人数据库。

阶段 D — 打磨

  1. 进出场动画统一Hub 已有滑入+淡入);暂停覆盖层半透明背板。
  2. 逐 Tab 核手柄默认焦点;确认 Cancel 在"子详情打开时只退一层"。

7. 涉及改动清单(速查)

类型 对象 改动
资产 UI_PauseMenuConfig.asset 删跳转项
代码 UIManager.cs OpenInventory toggleOpenMap 改为开 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 ScriptableObjects
  • BaseGames/Addressables/Validate Address Keys(新 SO/预制件地址常量化)
  • BaseGames/Tools/Maintenance/Physics2D Layer Matrix/Check
  • 运行期手测:背包键 toggle、L/R 切 7 个 Tab、地图键直达地图 Tab、暂停覆盖仅系统项、ESC 逐层退、全程手柄可达。

9. 待决问题

  1. 地图双形态:地图既作 Hub 的 Tab又是否保留可全屏脱离 Hub 的独立打开?(影响是否保留 PanelId.Map 双实例策略)
  2. 首发 Tab 集7 个是否全部首发,还是先上 地图/形态技能/护符/物品,能力·任务·图鉴二期?
  3. 图鉴数据源:解锁条件(首次击杀?需击杀 N 次解锁全条目?)与数据归属(敌人数据库 vs 独立 BestiaryEntrySO)。
  4. 暂停与统一屏的栈关系:是否允许在暂停覆盖里再开统一屏(一般不允许,二者互斥)。