GeWuYou a79f02c987 docs(api): 添加 Core API 参考文档与事件系统接口文档
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件
- 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明
- 提供完整的 API 使用示例路径、最佳实践与性能建议
- 包含架构图、依赖关系图与故障排查指南
- 添加测试用例参考与扩展方法说明
- [skip ci]
2026-01-21 23:45:10 +08:00

20 KiB
Raw Blame History

UI层级管理

**本文引用的文件** - [UiRouterBase.cs](file://GFramework.Game/ui/UiRouterBase.cs) - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs) - [IUiRoot.cs](file://GFramework.Game.Abstractions/ui/IUiRoot.cs) - [IUiPageBehavior.cs](file://GFramework.Game.Abstractions/ui/IUiPageBehavior.cs) - [UiLayer.cs](file://GFramework.Game.Abstractions/enums/UiLayer.cs) - [IUiFactory.cs](file://GFramework.Game.Abstractions/ui/IUiFactory.cs) - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs) - [UiTransitionPipeline.cs](file://GFramework.Game/ui/UiTransitionPipeline.cs) - [IUiTransitionHandler.cs](file://GFramework.Game.Abstractions/ui/IUiTransitionHandler.cs) - [GodotUiRegistry.cs](file://GFramework.Godot/ui/GodotUiRegistry.cs) - [IGodotUiRegistry.cs](file://GFramework.Godot/ui/IGodotUiRegistry.cs) - [GodotSceneRegistry.cs](file://GFramework.Godot/scene/GodotSceneRegistry.cs) - [IGodotSceneRegistry.cs](file://GFramework.Godot/scene/IGodotSceneRegistry.cs)

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

引言

本文件面向UI层级管理系统聚焦非栈层级Overlay、Modal、Toast等浮层的显示与隐藏控制系统性阐述Show/Hide方法的实现原理、UiLayer层级类型与Z-order管理、层级字典的数据结构与页面实例存储机制、层级清理与批量操作ClearLayer的实现与销毁策略并给出最佳实践、冲突处理与优先级管理建议。文中所有技术细节均来自仓库源码配合可视化图示帮助读者快速理解与落地。

项目结构

围绕UI层级管理的关键文件分布于以下模块

  • 抽象层定义UI页面行为、根节点接口、层级枚举、工厂接口等
  • 平台实现Godot平台的UI根节点与UI工厂实现
  • 路由与管线UI路由基类与过渡处理管线
  • 场景注册Godot场景注册表与UI注册表
graph TB
subgraph "抽象层"
A["IUiPageBehavior.cs"]
B["IUiRoot.cs"]
C["UiLayer.cs"]
D["IUiFactory.cs"]
E["IUiTransitionHandler.cs"]
end
subgraph "Godot实现"
F["GodotUiRoot.cs"]
G["GodotUiFactory.cs"]
H["GodotUiRegistry.cs"]
I["GodotSceneRegistry.cs"]
end
subgraph "路由与管线"
J["UiRouterBase.cs"]
K["UiTransitionPipeline.cs"]
end
J --> B
J --> D
J --> K
F --> B
G --> D
H --> G
I --> G

图表来源

章节来源

核心组件

  • UI路由基类UiRouterBase提供Page栈管理与非栈层级Overlay/Modal/Toast/Topmost的Show/Hide/ClearLayer等能力通过IUiRoot与IUiFactory协作完成页面生命周期与渲染顺序控制。
  • UI根节点GodotUiRootGodot平台实现负责将页面节点加入容器、设置Z序ZIndex并维护页面节点映射。
  • UI页面行为IUiPageBehavior统一的页面生命周期接口OnEnter/OnShow/OnHide/OnExit/OnPause/OnResume与交互阻断、遮罩需求等属性。
  • 层级枚举UiLayer定义Page、Overlay、Modal、Toast、Topmost五种层级用于Z-order分层与渲染优先级控制。
  • UI工厂IUiFactory/GodotUiFactory负责UI实例的创建、复用、回收与缓存清理支持实例策略AlwaysCreate/Reuse/Pooled
  • 过渡处理管线UiTransitionPipeline/IUiTransitionHandler提供BeforeChange/AfterChange阶段的扩展点支持按优先级与阶段过滤的处理器链路。

章节来源

架构总览

下图展示了UI层级管理的整体架构路由层协调工厂与根节点根节点负责渲染Z序管线层提供过渡扩展点。

graph TB
Router["UiRouterBase.cs<br/>路由与层级管理"]
Root["GodotUiRoot.cs<br/>UI根节点"]
Factory["GodotUiFactory.cs<br/>UI工厂"]
Layer["UiLayer.cs<br/>层级枚举"]
Page["IUiPageBehavior.cs<br/>页面行为"]
Pipe["UiTransitionPipeline.cs<br/>过渡管线"]
Handler["IUiTransitionHandler.cs<br/>处理器接口"]
Router --> Root
Router --> Factory
Router --> Pipe
Root --> Layer
Router --> Page
Pipe --> Handler

图表来源

详细组件分析

Show/Hide方法与层级字典

  • Show基于uiKey检查目标层级是否存在若不存在则通过工厂获取或创建实例写入层级字典调用UiRoot.AddUiPage(layer)设置Z序并触发OnEnter/OnShow。
  • Show基于实例直接写入层级字典并调用UiRoot.AddUiPage(layer)随后触发OnShow。
  • Hide调用OnExit/OnHide后依据destroy参数决定直接移除销毁或回收到工厂缓存池同时从层级字典移除。
  • ClearLayer遍历目标层级字典逐项调用Hide实现批量隐藏与回收/销毁。
sequenceDiagram
participant Caller as "调用方"
participant Router as "UiRouterBase"
participant Factory as "IUiFactory/GodotUiFactory"
participant Root as "GodotUiRoot"
participant Page as "IUiPageBehavior"
Caller->>Router : "Show(uiKey, layer)"
alt "层级未初始化"
Router->>Router : "初始化层级字典"
end
Router->>Router : "查找是否已存在"
alt "已存在"
Router->>Page : "OnEnter(param)"
Router->>Page : "OnShow()"
else "不存在"
Router->>Factory : "GetOrCreate(uiKey, policy)"
Factory-->>Router : "返回页面实例"
Router->>Router : "写入层级字典"
Router->>Root : "AddUiPage(Page, layer)"
Router->>Page : "OnEnter(param)"
Router->>Page : "OnShow()"
end

图表来源

章节来源

Z-order与层级字典数据结构

  • 层级字典_layers = Dictionary<UiLayer, Dictionary<string, IUiPageBehavior>>
    • 外层键为UiLayer内层键为页面uiKey值为页面实例
    • 作用:按层级组织非栈页面,支持快速查询、更新与批量清理
  • Z-order映射_layerZOrderMap = IReadOnlyDictionary<UiLayer, int>
    • 默认映射Page=0、Overlay=100、Modal=200、Toast=300、Topmost=400
    • 计算规则z = baseZOrder(layer) + orderInLayer
    • 设置方式GodotUiRoot.SetZOrder通过CanvasItem.ZIndex生效
flowchart TD
Start(["开始"]) --> CheckLayer["检查目标层级是否已初始化"]
CheckLayer --> |否| InitDict["初始化层级字典"]
CheckLayer --> |是| Lookup["按uiKey查找页面实例"]
Lookup --> Found{"已存在?"}
Found --> |是| CallLifecycle["调用OnEnter/OnShow"]
Found --> |否| GetOrCreate["工厂获取或创建实例"]
GetOrCreate --> WriteDict["写入层级字典"]
WriteDict --> AddRoot["UiRoot.AddUiPage(page, layer)"]
AddRoot --> SetZ["计算z=baseZOrder+orderInLayer并SetZOrder"]
SetZ --> End(["结束"])
CallLifecycle --> End

图表来源

章节来源

页面生命周期与交互阻断

  • 生命周期OnEnter → OnShow显示、OnHide隐藏但不销毁、OnExit完全退出、OnPause/OnResume栈式页面
  • 交互阻断IsModal、BlocksInput、RequiresMask等属性用于控制遮罩与输入拦截
  • 与根节点协作UiRoot.AddUiPage/RemoveUiPage负责节点挂载与卸载SetZOrder负责渲染顺序
classDiagram
class IUiPageBehavior {
+object View
+string Key
+bool IsAlive
+OnEnter(param)
+OnExit()
+OnPause()
+OnResume()
+OnHide()
+OnShow()
+bool IsModal
+bool BlocksInput
+bool RequiresMask
}
class GodotUiRoot {
+AddUiPage(child)
+AddUiPage(child, layer, orderInLayer)
+RemoveUiPage(child)
+SetZOrder(page, zOrder)
+GetVisiblePages()
}
IUiPageBehavior <.. GodotUiRoot : "通过View(Node)进行节点管理"

图表来源

章节来源

清理与批量操作ClearLayer

  • 清理流程遍历目标层级字典的keys逐个调用Hide(key, layer, destroy)
  • 销毁策略destroy=true时直接移除并销毁destroy=false时回收至工厂缓存池
  • 日志记录每次Hide/Clear均输出调试日志便于追踪
flowchart TD
S(["ClearLayer(layer, destroy)"]) --> CheckExists{"层级存在?"}
CheckExists --> |否| End(["结束"])
CheckExists --> |是| Keys["获取层级字典keys"]
Keys --> Loop{"遍历key"}
Loop --> |有| HideCall["Hide(key, layer, destroy)"]
HideCall --> Loop
Loop --> |无| Done["记录清理完成日志"] --> End

图表来源

章节来源

过渡处理与优先级管理

  • 管线执行BeforeChange阶段阻塞执行AfterChange阶段异步执行
  • 处理器注册按Priority升序执行可通过Phases与ShouldHandle过滤
  • 路由守卫Enter/Leave守卫可中断或允许切换支持CanInterrupt
sequenceDiagram
participant Router as "UiRouterBase"
participant Pipeline as "UiTransitionPipeline"
participant Handler as "IUiTransitionHandler"
Router->>Pipeline : "ExecuteAsync(event, BeforeChange)"
Pipeline->>Handler : "按Priority执行"
Handler-->>Pipeline : "完成"
Pipeline-->>Router : "返回"
Router->>Pipeline : "ExecuteAsync(event, AfterChange)"
Pipeline->>Handler : "按Priority执行(异步)"
Handler-->>Pipeline : "完成"
Pipeline-->>Router : "完成"

图表来源

章节来源

依赖关系分析

  • 路由对根节点与工厂的依赖UiRouterBase通过IUiRoot与IUiFactory协作解耦平台与实例管理
  • 工厂对注册表的依赖GodotUiFactory通过IGodotUiRegistry/GodotSceneRegistry加载场景资源
  • 根节点对层级映射的依赖GodotUiRoot根据UiLayer映射设置Z序
  • 管线对处理器的依赖UiTransitionPipeline维护处理器列表并按优先级执行
graph LR
Router["UiRouterBase"] --> Root["IUiRoot/GodotUiRoot"]
Router --> Factory["IUiFactory/GodotUiFactory"]
Factory --> Registry["IGodotUiRegistry/GodotUiRegistry"]
Root --> Layer["UiLayer"]
Router --> Pipeline["UiTransitionPipeline"]
Pipeline --> Handler["IUiTransitionHandler"]

图表来源

章节来源

性能考量

  • 实例复用与缓存通过IUiFactory的Reuse/Pooled策略减少频繁创建/销毁开销GodotUiFactory提供缓存队列与命中率统计
  • 批量清理ClearLayer按需销毁或回收避免长时间持有无用实例
  • Z序计算层级映射为常量时间查询SetZOrder直接设置CanvasItem.ZIndex开销极低
  • 过渡管线BeforeChange同步执行AfterChange异步执行降低主线程阻塞

章节来源

故障排查指南

  • 页面未显示
    • 检查是否在Page层级使用Show应使用Push
    • 检查UiRoot是否已初始化_uiContainer非空
    • 检查层级字典是否正确写入
  • 页面遮挡或顺序异常
    • 检查UiLayer映射与orderInLayer设置
    • 确认CanvasItem.ZIndex是否被其他逻辑覆盖
  • 页面无法隐藏或重复显示
    • 检查Hide调用是否传入正确的uiKey与layer
    • 确认destroy参数与工厂回收逻辑
  • 性能问题
    • 关注工厂缓存命中率与缓存大小
    • 避免频繁ClearLayer导致大量销毁/创建

章节来源

结论

本系统通过清晰的分层设计与接口抽象实现了非栈层级UI的灵活管理UiRouterBase负责业务编排与生命周期调度GodotUiRoot负责渲染顺序与节点管理IUiFactory负责实例化与缓存回收UiTransitionPipeline提供扩展点与优先级控制。借助层级字典与Z-order映射系统能够稳定地支持Overlay、Modal、Toast等浮层的并发显示与有序管理。

附录

最佳实践

  • 层级选择原则
    • Page使用Push/Pop管理页面栈适合主流程导航
    • Overlay用于覆盖层、菜单等不阻断下层交互
    • Modal模态窗口阻断下层交互并可带遮罩
    • Toast轻量提示短暂出现即消失
    • Topmost系统级弹窗或全屏加载
  • 性能优化
    • 优先使用Reuse/Pooled策略减少GC压力
    • 对高频出现的浮层进行预加载Preload/PreloadBatch
    • 合理设置orderInLayer避免频繁调整Z序
  • 内存管理
    • ClearLayer时根据场景选择destroy=false回收或true销毁
    • 定期清理缓存ClearCache/ClearAllCache防止内存泄漏
  • 冲突处理与优先级
    • 使用UiTransitionPipeline与IUiTransitionHandler实现前置校验与后置补偿
    • 通过路由守卫Enter/Leave控制切换时机与条件

典型场景与实现要点

  • 显示一个Overlay浮层
    • 调用Show(uiKey, UiLayer.Overlay, param, UiInstancePolicy.Reuse)
    • 若需同层多实例使用不同orderInLayer微调Z序
  • 显示一个Modal模态框
    • 调用Show(uiKey, UiLayer.Modal)
    • 页面行为需设置IsModal/BlocksInput/RequiresMask
  • 显示一个Toast提示
    • 调用Show(uiKey, UiLayer.Toast)
    • 设计短生命周期完成后立即Hide或等待自动清理
  • 批量清理某一层级
    • 调用ClearLayer(UiLayer.Overlay/Modal/Toast, destroy=false)
    • 或在退出场景时统一destroy=true彻底释放

章节来源