Files

48 lines
2.7 KiB
Markdown
Raw Permalink Normal View History

2026-07-08 19:53:15 +08:00
## UI 面板栈(UIPanelStack)技术说明
目标:统一管理“按 ESC 关闭”的 UI 面板顺序,避免关错面板;并支持“栈为空时按 ESC 打开暂停菜单”。
### 一、脚本清单
- 面板类型枚举:[UIPanelKind.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/UI/PanelStack/UIPanelKind.cs)
- 面板栈:[UIPanelStack.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/UI/PanelStack/UIPanelStack.cs)
- ESC 输入监听:[UIPanelStackInput.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/UI/PanelStack/UIPanelStackInput.cs)
### 二、运行机制
- `UIPanelStack` 维护一个栈(List),每个条目包含:
- `kind`:面板类型(用于后续扩展/调试)
- `root`:面板根 GameObject
- `closeAction`:关闭函数(优先使用;没有则默认 SetActive(false)
- `UIPanelStackInput` 每帧检测 ESC
- 若栈非空:关闭栈顶
- 若栈为空:调用 `TryOpenOnEscapeWhenEmpty()`(由暂停菜单注册)
### 三、核心 API
- `Push(UIPanelKind kind, GameObject root, Action closeAction)`
- 打开面板后调用,入栈。
- 同一个 root 会先 Remove 再 Push,保证栈内不重复。
- `Remove(GameObject root)`
- 面板主动关闭时调用,避免栈里残留。
- `CloseTop()`
- 关闭栈顶;会清理 inactive/root=null 的条目以防误关。
- `SetEscapeOpenHandler(Func<bool> handler)`
- 用于“栈为空时按 ESC 打开某个 UI”(例如 InGame 暂停菜单)。
### 四、项目内的接入点(已实现)
- Settings 面板:
- `SettingsController.OpenAtIndex(0)``Push(Settings, root, CloseOrBack)`
- `CloseOrBack()``Remove(root)`
- 相关实现:[SettingsController.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/UI/Settings/SettingsController.cs)
- InGame 暂停菜单:
- `InGamePauseMenuController.OnEnable()` 注册 `SetEscapeOpenHandler(TryOpenFromEscape)`
- 菜单打开时 Push(Pause, root, Close)
- 相关实现:[InGamePauseMenuController.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/UI/PauseMenu/InGamePauseMenuController.cs)
- 自动创建:
- `SettingsBootstrap` 会确保 UIPanelStack/UIPanelStackInput 存在(DontDestroyOnLoad
- 相关实现:[SettingsBootstrap.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/Core/SettingsSystem/SettingsBootstrap.cs)
### 五、使用规范(避免关错面板)
1) 只把“需要被 ESC 管理”的 UI 入栈(例如设置、暂停、弹窗)
2) 面板关闭时必须 Remove(或让 root 直接 inactive 也可,栈会清理,但 Remove 更确定)
3) 不在多个系统里各自监听 ESC 直接关 UI;统一交给 UIPanelStackInput 处理