Skip to content

AutoUiPage 生成器

为 Godot UI 页面生成 GetPage() 样板,统一页面键与层级声明。

概述

AutoUiPage 面向 GFramework 的 UI 路由场景。 当一个 Godot CanvasItem 节点本质上就是一个页面时,开发者通常要重复声明:

  • 页面 Key
  • 页面所在 UiLayer
  • IUiPageBehavior 缓存字段
  • GetPage() 工厂包装

AutoUiPage 会把这部分样板迁移到编译期生成。

基础使用

csharp
using GFramework.Godot.SourceGenerators.Abstractions;
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) 会生成字符串常量 UiKeyStrnameof(UiLayer.Page) 则会在生成代码中解析为对应的枚举成员 UiLayer.Page,并传入页面行为工厂。

生成的代码

csharp
// <auto-generated />
#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] 需要两个字符串参数:

参数类型说明
keystring页面 Key,例如 "MainMenu"
layerNamestringUiLayer 枚举成员名,例如 "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_001AutoUiPage 不支持嵌套类
GF_AutoBehavior_002目标类型没有继承 Godot.CanvasItem
GF_AutoBehavior_003提供的 UiLayer 名称无效
GF_AutoBehavior_004AutoUiPageAttribute 参数数量或类型不符合要求

组合示例

csharp
using GFramework.Godot.SourceGenerators.Abstractions;
using GFramework.Game.Abstractions.Enums;
using GFramework.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();
    }
}

相关文档

基于 Apache 2.0 许可证发布