--- title: AutoUiPage 生成器 description: 介绍 AutoUiPage 生成器如何为 Godot UI 页面生成页面包装入口。 --- # AutoUiPage 生成器 > 为 Godot UI 页面生成 `GetPage()` 样板,统一页面键与层级声明。 ## 概述 `AutoUiPage` 面向 GFramework 的 UI 路由场景。 当一个 Godot `CanvasItem` 节点本质上就是一个页面时,开发者通常要重复声明: - 页面 Key - 页面所在 `UiLayer` - `IUiPageBehavior` 缓存字段 - `GetPage()` 工厂包装 `AutoUiPage` 会把这部分样板迁移到编译期生成。 该特性当前位于 `GFramework.Godot.SourceGenerators.Abstractions.UI` 命名空间。 ## 基础使用 ```csharp using GFramework.Godot.SourceGenerators.Abstractions.UI; using GFramework.Game.Abstractions.Enums; using Godot; [AutoUiPage(nameof(UiKey.MainMenu), nameof(UiLayer.Page))] public partial class MainMenu : Control { public override void _Ready() { _ = GetPage(); } } ``` 上面的 `nameof(UiKey.MainMenu)` 会生成字符串常量 `UiKeyStr`,`nameof(UiLayer.Page)` 则会在生成代码中解析为对应的枚举成员 `UiLayer.Page`,并传入页面行为工厂。 ## 生成的代码 ```csharp // #nullable enable partial class MainMenu { private global::GFramework.Game.Abstractions.UI.IUiPageBehavior? __autoUiPageBehavior_Generated; public static string UiKeyStr => "MainMenu"; public global::GFramework.Game.Abstractions.UI.IUiPageBehavior GetPage() { return __autoUiPageBehavior_Generated ??= global::GFramework.Godot.UI.UiPageBehaviorFactory.Create( this, UiKeyStr, global::GFramework.Game.Abstractions.Enums.UiLayer.Page); } } ``` ## 参数说明 `[AutoUiPage]` 需要两个字符串参数: | 参数 | 类型 | 说明 | |-------------|----------|-----------------------------| | `key` | `string` | 页面 Key,例如 `"MainMenu"` | | `layerName` | `string` | `UiLayer` 枚举成员名,例如 `"Page"` | 推荐写法: ```csharp [AutoUiPage(nameof(UiKey.Inventory), nameof(UiLayer.Overlay))] ``` 这样可以避免硬编码字符串拼写错误。 ## 适用场景 推荐用于: - 主菜单、设置页、背包页、弹窗根节点 - Godot 场景中已经明确是“一个页面”的 `Control` / `CanvasLayer` / `Panel` - 只需要标准页面行为包装,而不需要自定义复杂工厂逻辑的页面 不推荐用于: - 临时子控件、列表项、纯视觉碎片节点 - 页面行为创建前必须注入额外上下文参数的节点 - 还未接入 GFramework UI 路由体系的老页面 ## 使用约束 - 目标类型必须是 `partial class` - 不支持嵌套类 - 目标类型必须继承 `Godot.CanvasItem` - `layerName` 必须对应 `GFramework.Game.Abstractions.Enums.UiLayer` 上的有效成员名 - 不要自行声明同名 `GetPage()` 方法 ## 生命周期边界 `AutoUiPage` 只生成页面行为样板,不会自动织入 Godot 生命周期。 它不会替你生成或调用: - `_Ready()` - `_ExitTree()` - 页面打开关闭回调 - 节点注入或上下文注入 如果页面同时使用了 `[GetNode]`、`[BindNodeSignal]`、`[GetAll]` 等特性,仍然需要在你自己的生命周期方法中显式调用对应的生成方法。 ## 诊断信息 | 诊断 ID | 含义 | |-----------------------|------------------------------------| | `GF_Common_Class_001` | 目标类型不是 `partial`,生成被跳过 | | `GF_Common_Class_002` | 宿主类型已声明 `GetPage()`,与生成代码冲突 | | `GF_AutoBehavior_001` | `AutoUiPage` 不支持嵌套类 | | `GF_AutoBehavior_002` | 目标类型没有继承 `Godot.CanvasItem` | | `GF_AutoBehavior_003` | 提供的 `UiLayer` 名称无效 | | `GF_AutoBehavior_004` | `AutoUiPageAttribute` 参数数量或类型不符合要求 | ## 组合示例 ```csharp using GFramework.Godot.SourceGenerators.Abstractions.UI; using GFramework.Game.Abstractions.Enums; using GFramework.Core.SourceGenerators.Abstractions.Rule; using Godot; [ContextAware] [GetAll] [AutoUiPage(nameof(UiKey.PauseMenu), nameof(UiLayer.Modal))] public partial class PauseMenu : Control { [GetNode] private Button _resumeButton = null!; public override void _Ready() { __InjectGetNodes_Generated(); __InjectContextBindings_Generated(); _ = GetPage(); } } ``` ## 相关文档 - [源码生成器总览](./index.md) - [GetNode 生成器](./get-node-generator.md) - [BindNodeSignal 生成器](./bind-node-signal-generator.md)