2.7 KiB
2.7 KiB
UI 面板栈(UIPanelStack)技术说明
目标:统一管理“按 ESC 关闭”的 UI 面板顺序,避免关错面板;并支持“栈为空时按 ESC 打开暂停菜单”。
一、脚本清单
- 面板类型枚举:UIPanelKind.cs
- 面板栈:UIPanelStack.cs
- ESC 输入监听:UIPanelStackInput.cs
二、运行机制
UIPanelStack维护一个栈(List),每个条目包含:kind:面板类型(用于后续扩展/调试)root:面板根 GameObjectcloseAction:关闭函数(优先使用;没有则默认 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
- InGame 暂停菜单:
InGamePauseMenuController.OnEnable()注册SetEscapeOpenHandler(TryOpenFromEscape)- 菜单打开时 Push(Pause, root, Close)
- 相关实现:InGamePauseMenuController.cs
- 自动创建:
SettingsBootstrap会确保 UIPanelStack/UIPanelStackInput 存在(DontDestroyOnLoad)- 相关实现:SettingsBootstrap.cs
五、使用规范(避免关错面板)
- 只把“需要被 ESC 管理”的 UI 入栈(例如设置、暂停、弹窗)
- 面板关闭时必须 Remove(或让 root 直接 inactive 也可,栈会清理,但 Remove 更确定)
- 不在多个系统里各自监听 ESC 直接关 UI;统一交给 UIPanelStackInput 处理