Files
Echo/Assets/_Project/Docs/UIPanelStack_Technical_Reference.md
2026-07-08 20:42:51 +08:00

2.7 KiB
Raw Permalink Blame History

UI 面板栈(UIPanelStack)技术说明

目标:统一管理“按 ESC 关闭”的 UI 面板顺序,避免关错面板;并支持“栈为空时按 ESC 打开暂停菜单”。

一、脚本清单

二、运行机制

  • 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
  • InGame 暂停菜单:
    • InGamePauseMenuController.OnEnable() 注册 SetEscapeOpenHandler(TryOpenFromEscape)
    • 菜单打开时 Push(Pause, root, Close)
    • 相关实现:InGamePauseMenuController.cs
  • 自动创建:
    • SettingsBootstrap 会确保 UIPanelStack/UIPanelStackInput 存在(DontDestroyOnLoad
    • 相关实现:SettingsBootstrap.cs

五、使用规范(避免关错面板)

  1. 只把“需要被 ESC 管理”的 UI 入栈(例如设置、暂停、弹窗)
  2. 面板关闭时必须 Remove(或让 root 直接 inactive 也可,栈会清理,但 Remove 更确定)
  3. 不在多个系统里各自监听 ESC 直接关 UI;统一交给 UIPanelStackInput 处理