# Godot UI系统 **本文引用的文件** - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs) - [GodotUiRegistry.cs](file://GFramework.Godot/ui/GodotUiRegistry.cs) - [IGodotUiRegistry.cs](file://GFramework.Godot/ui/IGodotUiRegistry.cs) - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs) - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs) - [IUiFactory.cs](file://GFramework.Game.Abstractions/ui/IUiFactory.cs) - [IUiRoot.cs](file://GFramework.Game.Abstractions/ui/IUiRoot.cs) - [IUiPageBehavior.cs](file://GFramework.Game.Abstractions/ui/IUiPageBehavior.cs) - [IUiPage.cs](file://GFramework.Game.Abstractions/ui/IUiPage.cs) - [UiLayer.cs](file://GFramework.Game.Abstractions/enums/UiLayer.cs) - [UiCacheConfig.cs](file://GFramework.Game.Abstractions/ui/UiCacheConfig.cs) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本指南面向希望在Godot引擎中构建高性能、可维护UI系统的开发者。文档围绕以下目标展开: - 全面解析Godot UI系统的整体架构:UI工厂模式、注册机制、根节点管理。 - 深入讲解GodotUiFactory的UI对象创建流程:CanvasItem实例化、属性配置、生命周期管理与缓存策略。 - 说明GodotUiRegistry的UI注册与管理:UI页面注册、查找、缓存配置。 - 详解GodotUiRoot的根节点控制:场景树管理、层级控制、事件传递。 - 解释CanvasItemUiPageBehavior的页面行为管理:进入/退出、状态管理、动画与可见性控制。 - 提供最佳实践:性能优化、内存管理、事件处理与集成步骤。 ## 项目结构 Godot UI系统位于GFramework.Godot模块中,采用分层与职责分离设计: - UI工厂:负责UI页面实例的创建、缓存与回收。 - UI注册表:负责UI场景资源的注册与检索。 - UI根节点:负责场景树组织、层级与可见性管理。 - 页面行为:封装CanvasItem页面的生命周期与状态控制。 ```mermaid graph TB subgraph "Godot UI模块" Factory["GodotUiFactory
工厂与缓存"] Registry["GodotUiRegistry
场景注册"] Root["GodotUiRoot
根节点管理"] Behavior["CanvasItemUiPageBehavior
页面行为"] end subgraph "抽象接口层" IFac["IUiFactory"] IReg["IGodotUiRegistry"] IRoot["IUiRoot"] IBeh["IUiPageBehavior"] IPage["IUiPage"] Layer["UiLayer"] Cfg["UiCacheConfig"] end Factory --> Registry Factory --> Behavior Root --> Behavior Behavior --> IBeh Factory --> IFac Registry --> IReg Root --> IRoot Behavior --> IPage Root --> Layer Factory --> Cfg ``` 图表来源 - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L16-L463) - [GodotUiRegistry.cs](file://GFramework.Godot/ui/GodotUiRegistry.cs#L11-L12) - [IGodotUiRegistry.cs](file://GFramework.Godot/ui/IGodotUiRegistry.cs#L1-L10) - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs#L11-L142) - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L12-L113) - [IUiFactory.cs](file://GFramework.Game.Abstractions/ui/IUiFactory.cs#L10-L87) - [IUiRoot.cs](file://GFramework.Game.Abstractions/ui/IUiRoot.cs#L9-L43) - [IUiPageBehavior.cs](file://GFramework.Game.Abstractions/ui/IUiPageBehavior.cs#L6-L72) - [IUiPage.cs](file://GFramework.Game.Abstractions/ui/IUiPage.cs#L7-L39) - [UiLayer.cs](file://GFramework.Game.Abstractions/enums/UiLayer.cs#L7-L34) - [UiCacheConfig.cs](file://GFramework.Game.Abstractions/ui/UiCacheConfig.cs#L10-L62) 章节来源 - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L16-L463) - [GodotUiRegistry.cs](file://GFramework.Godot/ui/GodotUiRegistry.cs#L11-L12) - [IGodotUiRegistry.cs](file://GFramework.Godot/ui/IGodotUiRegistry.cs#L1-L10) - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs#L11-L142) - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L12-L113) - [IUiFactory.cs](file://GFramework.Game.Abstractions/ui/IUiFactory.cs#L10-L87) - [IUiRoot.cs](file://GFramework.Game.Abstractions/ui/IUiRoot.cs#L9-L43) - [IUiPageBehavior.cs](file://GFramework.Game.Abstractions/ui/IUiPageBehavior.cs#L6-L72) - [IUiPage.cs](file://GFramework.Game.Abstractions/ui/IUiPage.cs#L7-L39) - [UiLayer.cs](file://GFramework.Game.Abstractions/enums/UiLayer.cs#L7-L34) - [UiCacheConfig.cs](file://GFramework.Game.Abstractions/ui/UiCacheConfig.cs#L10-L62) ## 核心组件 - GodotUiFactory:实现IUiFactory,负责UI页面实例的创建、缓存、预加载、回收与统计;支持多种实例策略(AlwaysCreate、Reuse、Pooled)与缓存淘汰策略(LRU/LFU)。 - GodotUiRegistry:实现IGodotUiRegistry,基于键值对注册与管理PackedScene资源。 - GodotUiRoot:实现IUiRoot,负责UI场景树的容器节点创建、页面添加/移除、层级Z序设置与可见页面查询。 - CanvasItemUiPageBehavior:实现IUiPageBehavior,封装CanvasItem页面的生命周期(进入、退出、暂停、恢复、显示、隐藏)、状态标志(模态、遮罩、阻断输入)与Godot节点处理(进程开关、可见性)。 章节来源 - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L16-L463) - [GodotUiRegistry.cs](file://GFramework.Godot/ui/GodotUiRegistry.cs#L11-L12) - [IGodotUiRegistry.cs](file://GFramework.Godot/ui/IGodotUiRegistry.cs#L1-L10) - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs#L11-L142) - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L12-L113) - [IUiFactory.cs](file://GFramework.Game.Abstractions/ui/IUiFactory.cs#L10-L87) - [IUiRoot.cs](file://GFramework.Game.Abstractions/ui/IUiRoot.cs#L9-L43) - [IUiPageBehavior.cs](file://GFramework.Game.Abstractions/ui/IUiPageBehavior.cs#L6-L72) - [IUiPage.cs](file://GFramework.Game.Abstractions/ui/IUiPage.cs#L7-L39) - [UiLayer.cs](file://GFramework.Game.Abstractions/enums/UiLayer.cs#L7-L34) - [UiCacheConfig.cs](file://GFramework.Game.Abstractions/ui/UiCacheConfig.cs#L10-L62) ## 架构总览 系统采用“工厂+注册表+根节点+行为”的分层架构: - 工厂通过注册表获取场景资源,实例化CanvasItem节点,并包装为页面行为。 - 根节点统一管理场景树与层级,确保渲染顺序与交互顺序正确。 - 页面行为负责生命周期与状态,协调Godot节点的显示、暂停、输入处理等。 ```mermaid sequenceDiagram participant Caller as "调用方" participant Factory as "GodotUiFactory" participant Registry as "GodotUiRegistry" participant Scene as "PackedScene" participant Node as "CanvasItem节点" participant Behavior as "CanvasItemUiPageBehavior" Caller->>Factory : "GetOrCreate(uiKey, 策略)" alt Reuse/Pooled Factory->>Factory : "检查缓存队列" opt 命中缓存 Factory-->>Caller : "返回缓存实例" end opt 未命中缓存 Factory->>Registry : "Get(uiKey)" Registry-->>Factory : "PackedScene" Factory->>Scene : "Instantiate()" Scene-->>Factory : "Node" Factory->>Behavior : "构造行为包装" Factory-->>Caller : "返回新实例" end else AlwaysCreate Factory->>Registry : "Get(uiKey)" Registry-->>Factory : "PackedScene" Factory->>Scene : "Instantiate()" Scene-->>Factory : "Node" Factory->>Behavior : "构造行为包装" Factory-->>Caller : "返回新实例" end ``` 图表来源 - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L67-L97) - [GodotUiRegistry.cs](file://GFramework.Godot/ui/GodotUiRegistry.cs#L11-L12) - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L12-L28) ## 详细组件分析 ### GodotUiFactory:UI工厂与缓存 - 职责 - 实例创建:根据uiKey从注册表获取场景并实例化,包装为IUiPageBehavior。 - 缓存策略:支持Reuse(复用缓存)、Pooled(池化预加载)、AlwaysCreate(每次都新建)。 - 预加载与回收:批量预热缓存,回收时隐藏并更新统计与访问追踪。 - 淘汰策略:LRU按最后访问时间淘汰,LFU按访问频次淘汰。 - 统计与配置:缓存大小、命中率、最后访问时间;最大缓存数、淘汰策略、访问后过期。 - 关键数据结构 - 缓存队列:按uiKey分组的实例队列。 - 访问追踪:LRU时间队列与LFU访问计数。 - 实例追踪:用于统一清理。 - 生命周期 - OnEnter:触发页面生命周期回调(若存在)。 - OnExit:触发页面生命周期回调并释放节点。 - OnPause/OnResume:控制节点的处理、物理与输入处理开关。 - OnHide/OnShow:隐藏/显示节点并恢复处理。 ```mermaid classDiagram class GodotUiFactory { -_registry : IGodotUiRegistry -_cachedInstances : Dictionary> -_allInstances : Dictionary> -_cacheConfigs : Dictionary -_cacheStatistics : Dictionary -_accessTimeQueue : Dictionary> -_accessCount : Dictionary +GetOrCreate(uiKey, policy) IUiPageBehavior +Create(uiKey) IUiPageBehavior +Preload(uiKey, count) void +PreloadBatch(uiKeys) void +Recycle(page) void +ClearCache(uiKey) void +ClearAllCache() void +HasCached(uiKey) bool +GetCacheConfig(uiKey) UiCacheConfig +SetCacheConfig(uiKey, config) void +RemoveCacheConfig(uiKey) void +GetCacheStatistics() IDictionary -GetCachedOrCreate(uiKey) IUiPageBehavior -GetFromPoolOrCreate(uiKey) IUiPageBehavior -DestroyInstance(page) void -UpdateStatisticsOnRecycle(uiKey) void -UpdateStatisticsOnHit(uiKey) void -UpdateStatisticsOnMiss(uiKey) void -UpdateAccessTracking(uiKey, instance) void -CheckAndEvict(uiKey) void -EvictLru(uiKey) void -EvictLfu(uiKey) void } class IUiFactory class IGodotUiRegistry class UiCacheConfig class IUiPageBehavior GodotUiFactory ..|> IUiFactory GodotUiFactory --> IGodotUiRegistry : "依赖" GodotUiFactory --> UiCacheConfig : "配置" GodotUiFactory --> IUiPageBehavior : "创建/回收" ``` 图表来源 - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L16-L463) - [IUiFactory.cs](file://GFramework.Game.Abstractions/ui/IUiFactory.cs#L10-L87) - [IGodotUiRegistry.cs](file://GFramework.Godot/ui/IGodotUiRegistry.cs#L1-L10) - [UiCacheConfig.cs](file://GFramework.Game.Abstractions/ui/UiCacheConfig.cs#L10-L62) - [IUiPageBehavior.cs](file://GFramework.Game.Abstractions/ui/IUiPageBehavior.cs#L6-L72) 章节来源 - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L67-L463) - [IUiFactory.cs](file://GFramework.Game.Abstractions/ui/IUiFactory.cs#L10-L87) - [UiCacheConfig.cs](file://GFramework.Game.Abstractions/ui/UiCacheConfig.cs#L10-L62) ### GodotUiRegistry:UI注册与管理 - 职责 - 基于键值对注册与管理PackedScene资源,提供Get(uiKey)获取场景。 - 设计 - 继承KeyValueRegistryBase,使用字符串键与PackedScene值。 - 实现IGodotUiRegistry接口,作为GodotUiFactory的依赖。 ```mermaid classDiagram class GodotUiRegistry { +Get(key) PackedScene +Set(key, value) void +TryGet(key, out value) bool +ContainsKey(key) bool +Remove(key) bool } class IGodotUiRegistry class KeyValueRegistryBase~string,PackedScene~ GodotUiRegistry ..|> IGodotUiRegistry GodotUiRegistry --|> KeyValueRegistryBase~string,PackedScene~ ``` 图表来源 - [GodotUiRegistry.cs](file://GFramework.Godot/ui/GodotUiRegistry.cs#L11-L12) - [IGodotUiRegistry.cs](file://GFramework.Godot/ui/IGodotUiRegistry.cs#L1-L10) 章节来源 - [GodotUiRegistry.cs](file://GFramework.Godot/ui/GodotUiRegistry.cs#L11-L12) - [IGodotUiRegistry.cs](file://GFramework.Godot/ui/IGodotUiRegistry.cs#L1-L10) ### GodotUiRoot:UI根节点控制 - 职责 - 创建UiContainer作为UI根节点的子节点。 - 添加/移除UI页面,设置Z序以控制渲染层级。 - 查询当前可见页面。 - 层级映射 - 默认UiLayer到Z序映射:Page=0、Overlay=100、Modal=200、Toast=300、Topmost=400。 - 交互 - 通过IUiPageBehavior.View获取CanvasItem节点并设置ZIndex。 ```mermaid flowchart TD Start(["初始化"]) --> Ready["_Ready()
创建UiContainer"] Ready --> Add["AddUiPage(child[, layer, orderInLayer])"] Add --> GetNode["从页面行为获取节点"] GetNode --> CheckParent{"父节点是UiContainer?"} CheckParent --> |否| Attach["添加到UiContainer"] CheckParent --> |是| SetZ["计算Z序并设置"] Attach --> SetZ SetZ --> End(["完成"]) Remove["RemoveUiPage(child)"] --> Detach["从UiContainer移除"] Detach --> End ``` 图表来源 - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs#L45-L141) - [IUiRoot.cs](file://GFramework.Game.Abstractions/ui/IUiRoot.cs#L9-L43) - [UiLayer.cs](file://GFramework.Game.Abstractions/enums/UiLayer.cs#L7-L34) 章节来源 - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs#L11-L142) - [IUiRoot.cs](file://GFramework.Game.Abstractions/ui/IUiRoot.cs#L9-L43) - [UiLayer.cs](file://GFramework.Game.Abstractions/enums/UiLayer.cs#L7-L34) ### CanvasItemUiPageBehavior:页面行为管理 - 职责 - 封装CanvasItem节点的生命周期与状态:进入、退出、暂停、恢复、显示、隐藏。 - 控制节点的处理开关(process/physics_process/input)。 - 管理模态、遮罩与输入阻断标志。 - 关键点 - OnExit:调用页面生命周期回调并释放节点。 - OnShow:显示节点并恢复处理。 - OnHide:隐藏节点并调用页面生命周期回调。 ```mermaid classDiagram class CanvasItemUiPageBehavior~T~ { -owner : T -key : string -_page : IUiPage +View object +Key string +IsAlive bool +OnEnter(param) void +OnExit() void +OnPause() void +OnResume() void +OnHide() void +OnShow() void +IsModal bool +BlocksInput bool +RequiresMask bool } class IUiPageBehavior class IUiPage class CanvasItem CanvasItemUiPageBehavior~T~ ..|> IUiPageBehavior CanvasItemUiPageBehavior~T~ --> IUiPage : "可选委托" CanvasItemUiPageBehavior~T~ --> CanvasItem : "持有" ``` 图表来源 - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L12-L113) - [IUiPageBehavior.cs](file://GFramework.Game.Abstractions/ui/IUiPageBehavior.cs#L6-L72) - [IUiPage.cs](file://GFramework.Game.Abstractions/ui/IUiPage.cs#L7-L39) 章节来源 - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L12-L113) - [IUiPageBehavior.cs](file://GFramework.Game.Abstractions/ui/IUiPageBehavior.cs#L6-L72) - [IUiPage.cs](file://GFramework.Game.Abstractions/ui/IUiPage.cs#L7-L39) ## 依赖分析 - 组件耦合 - GodotUiFactory依赖IGodotUiRegistry与IUiPageBehavior,通过场景键管理实例生命周期。 - GodotUiRoot依赖IUiPageBehavior.View(CanvasItem)进行层级控制。 - CanvasItemUiPageBehavior依赖IUiPage(可选)以转发生命周期事件。 - 外部依赖 - Godot引擎的PackedScene与CanvasItem节点模型。 - GFramework核心扩展(如节点释放辅助)。 ```mermaid graph LR Factory["GodotUiFactory"] --> Reg["IGodotUiRegistry"] Factory --> Beh["IUiPageBehavior"] Root["GodotUiRoot"] --> Beh BehImpl["CanvasItemUiPageBehavior"] --> Page["IUiPage"] Root --> Layer["UiLayer"] Factory --> Cfg["UiCacheConfig"] ``` 图表来源 - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L32-L96) - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs#L16-L118) - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L15-L96) - [UiLayer.cs](file://GFramework.Game.Abstractions/enums/UiLayer.cs#L7-L34) - [UiCacheConfig.cs](file://GFramework.Game.Abstractions/ui/UiCacheConfig.cs#L10-L62) 章节来源 - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L32-L96) - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs#L16-L118) - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L15-L96) - [UiLayer.cs](file://GFramework.Game.Abstractions/enums/UiLayer.cs#L7-L34) - [UiCacheConfig.cs](file://GFramework.Game.Abstractions/ui/UiCacheConfig.cs#L10-L62) ## 性能考虑 - 实例策略选择 - Reuse:适合频繁切换的页面,降低GC压力。 - Pooled:池化预热,避免首帧卡顿。 - AlwaysCreate:适合一次性页面或状态复杂需隔离的页面。 - 缓存配置 - 合理设置MaxCacheSize与EvictionPolicy(LRU/LFU),结合ExpireAfterAccess减少常驻内存。 - 使用GetCacheStatistics监控命中率,指导容量调整。 - 节点生命周期 - OnPause/OnResume精准控制process/physics_process/input,避免无用更新。 - OnExit及时释放节点,防止内存泄漏。 - 场景树管理 - 通过Z序控制渲染顺序,避免不必要的重绘。 - 批量预加载与延迟回收,平衡内存与CPU。 ## 故障排查指南 - 常见问题与定位 - “页面节点为空”:确认IUiPageBehavior.View为CanvasItem且已正确实例化。 - “层级无效”:检查UiLayer映射与Z序计算,确保未越界。 - “缓存未命中”:检查UiInstancePolicy与缓存配置,查看统计信息。 - “内存泄漏”:确认OnExit路径是否调用节点释放,以及实例追踪集合是否清理。 - 日志与统计 - 工厂日志记录创建、回收、预加载与淘汰过程,便于定位异常。 - 缓存统计包含命中/未命中计数、命中率与最后访问时间。 章节来源 - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L95-L157) - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs#L61-L118) - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L50-L96) ## 结论 Godot UI系统通过清晰的职责划分与可配置的缓存策略,实现了高效、可控的UI生命周期管理。结合根节点的层级控制与页面行为的状态机式管理,能够满足从简单页面到复杂模态交互的多样化需求。建议在实际项目中: - 明确页面类型与实例策略,合理配置缓存。 - 严格遵循生命周期回调,避免资源泄漏。 - 利用Z序与遮罩策略保证交互一致性与视觉层次。 ## 附录 ### 集成步骤(概览) - 注册场景资源 - 使用GodotUiRegistry注册PackedScene,键为uiKey。 - 创建UI工厂 - 在架构上下文中注入GodotUiFactory与GodotUiRegistry。 - 构建根节点 - 在场景中挂载GodotUiRoot,确保其作为UI容器的根。 - 使用页面行为 - 通过GodotUiFactory.GetOrCreate(uiKey, 策略)获取页面行为,再由GodotUiRoot.AddUiPage(child, layer, orderInLayer)加入场景树。 - 生命周期管理 - 在页面逻辑中实现IUiPage接口(可选),以便CanvasItemUiPageBehavior转发生命周期事件。 章节来源 - [GodotUiRegistry.cs](file://GFramework.Godot/ui/GodotUiRegistry.cs#L11-L12) - [GodotUiFactory.cs](file://GFramework.Godot/ui/GodotUiFactory.cs#L67-L97) - [GodotUiRoot.cs](file://GFramework.Godot/ui/GodotUiRoot.cs#L59-L89) - [CanvasItemUiPageBehavior.cs](file://GFramework.Godot/ui/CanvasItemUiPageBehavior.cs#L39-L96)