diff --git a/ai-plan/public/documentation-governance-and-refresh/todos/documentation-governance-and-refresh-tracking.md b/ai-plan/public/documentation-governance-and-refresh/todos/documentation-governance-and-refresh-tracking.md
index df7f9ff1..3dc3a5e7 100644
--- a/ai-plan/public/documentation-governance-and-refresh/todos/documentation-governance-and-refresh-tracking.md
+++ b/ai-plan/public/documentation-governance-and-refresh/todos/documentation-governance-and-refresh-tracking.md
@@ -7,19 +7,19 @@
## 当前恢复点
-- 恢复点编号:`DOCUMENTATION-GOVERNANCE-REFRESH-RP-012`
+- 恢复点编号:`DOCUMENTATION-GOVERNANCE-REFRESH-RP-013`
- 当前阶段:`Phase 3`
- 当前焦点:
- 已建立统一公开 skill:`.agents/skills/gframework-doc-refresh/`
- 文档重构入口已从“按 guide/tutorial/api 类型拆 skill”收口为“按源码模块驱动文档刷新”
- - PR #268 的当前未解决 review 线程已进入收口:Scene/UI 标题层级修正、共享脚本 review 修复、`gframework-pr-review` 多 AI reviewer 支持补齐
- - `Godot.SourceGenerators` 的 4 个高风险专题页已按当前实现重写,下一轮转入 tutorial 收口与 PR thread 收口
+ - `docs/zh-CN/tutorials/godot-integration.md` 已按当前实现重写,教程入口不再复刻旧 Godot API 叙述
+ - `docs/zh-CN/godot/index.md` 与 `docs/zh-CN/godot/architecture.md` 仍保留同类旧写法,成为下一轮高优先级收口对象
## 当前状态摘要
- 文档治理规则已收口到仓库规范,README、站点入口与采用链路不再依赖旧文档自证
-- 高优先级模块入口与 `core` 关键专题页已回到可作为默认导航入口的状态,本轮计划中的 `core` 剩余高风险页面已完成收口
-- 当前主题仍是 active topic,因为 `source-generators` 栏目下的 Godot 相关页面仍可能包含与实现漂移的旧内容,且统一 skill 还需要在该场景上继续落地使用
+- 高优先级模块入口、`core` 关键专题页与 `tutorials/godot-integration.md` 已回到“以源码 / 测试 / README 为准”的状态
+- 当前主题仍是 active topic,因为 `docs/zh-CN/godot/` 栏目入口和架构页仍有旧 API / 旧接入路径叙述,Godot 文档链路尚未完全收口
## 当前活跃事实
@@ -65,6 +65,9 @@
明确当前不会自动生成 `_Ready()` / `_ExitTree()`
- `docs/zh-CN/source-generators/auto-register-exported-collections-generator.md` 已补齐 frontmatter,并改成“成员形状、registry 匹配规则、null-skip 行为、编译期诊断与 CoreGrid 真实采用路径”的结构,
明确生成器依赖的是实例可读集合成员与可读 registry 成员,不要求成员必须带 `[Export]`
+- `docs/zh-CN/tutorials/godot-integration.md` 已改成“包关系、`project.godot` 接线、`[GetNode]` / `[BindNodeSignal]` 协作顺序、运行时扩展边界、迁移提醒”的结构,
+ 不再把 `GetNodeX`、`CreateSignalBuilder`、`AbstractGodotModule` 默认化叙述为当前推荐路径
+- `docs/zh-CN/tutorials/index.md` 中 Godot 教程入口摘要已同步改成“项目级配置 + 生成器协作 + 生命周期边界”,不再继续宣传对象池 / 性能优化式旧范围
- `.agents/skills/gframework-doc-refresh/SKILL.md` 已改成标准 YAML frontmatter skill,并明确支持模块输入、证据顺序、输出优先级与验证步骤
- `.agents/skills/gframework-doc-refresh/SKILL.md` 的 `description` 已加引号,修复 `Recommended command:` 中冒号导致的
invalid YAML skill 加载警告
@@ -85,9 +88,10 @@
`godot-project-generator.md`、`get-node-generator.md`、`bind-node-signal-generator.md` 与 `auto-register-exported-collections-generator.md`
已完成收口;
继续按源码、测试、`*.csproj` 与 `ai-libs/` 下已验证参考实现核对剩余 Godot 相关页面,不把旧文档当事实来源
-- 教程失真回流风险:`docs/zh-CN/tutorials/godot-integration.md` 仍保留旧 API 与旧模块叙述,可能把已清理掉的旧说法重新带回专题页
- - 缓解措施:本轮已确认 `GetNodeX`、`AbstractGodotModule`、`InstallGodotModule` 与 `GFramework.Godot.Pool` 等旧引用仍存在;
- 下一轮优先按当前 `GFramework.Godot` / `Godot.SourceGenerators` 实现重写或拆分该教程
+- Godot 栏目入口失真风险:`docs/zh-CN/godot/index.md` 与 `docs/zh-CN/godot/architecture.md` 仍保留 `GetNodeX`、
+ `CreateSignalBuilder`、`InstallGodotModule(...).Wait()` 等旧叙述,可能覆盖新教程的采用路径
+ - 缓解措施:本轮已完成 tutorial 收口;下一轮优先按当前 `GFramework.Godot` / `GFramework.Godot.SourceGenerators` /
+ `ai-libs/CoreGrid` 的真实采用路径重写 `godot/index.md`,并评估 `godot/architecture.md` 的最小收口范围
- 采用路径误导风险:根聚合包与模块边界若再次被写错,会继续误导消费者的包选择
- 缓解措施:保持“源码与包关系优先”的证据顺序,改动采用说明时同步核对包依赖与生成器 wiring
- 模块映射不全风险:统一 skill 若遗漏模块别名、测试项目或 docs 栏目映射,会让后续扫描阶段直接失焦
@@ -132,10 +136,12 @@
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/get-node-generator.md`
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/bind-node-signal-generator.md`
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/auto-register-exported-collections-generator.md`
+- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/tutorials/godot-integration.md`
+- `rg -n "GetNodeX|CreateSignalBuilder|GodotGameArchitecture|AbstractGodotModule|InstallGodotModule\(|GFramework\.Godot\.Pool" docs/zh-CN/godot docs/zh-CN/tutorials -S`
- `cd docs && bun run build`
## 下一步
-1. 优先重写或拆分 `docs/zh-CN/tutorials/godot-integration.md`,先移除 `GetNodeX`、`AbstractGodotModule`、`InstallGodotModule` 等旧 API 叙述
-2. 下一次推送后先重新执行 `$gframework-pr-review`,确认 PR #268 的 CodeRabbit / Greptile open thread 是否按预期收敛
-3. 若 tutorial 收口后 active 内容再次变长,把本阶段已完成的 Godot 生成器专题历史迁入 topic `archive/`
+1. 优先重写 `docs/zh-CN/godot/index.md`,清掉 `GetNodeX`、`CreateSignalBuilder`、`InstallGodotModule(...)` 默认化叙述
+2. 视 `godot/index.md` 收口结果,决定是否同步压缩 `docs/zh-CN/godot/architecture.md`,避免两页继续互相复制旧接入路径
+3. 下一次推送后重新执行 `$gframework-pr-review`,确认 PR #268 的 CodeRabbit / Greptile open thread 是否按预期收敛
diff --git a/ai-plan/public/documentation-governance-and-refresh/traces/documentation-governance-and-refresh-trace.md b/ai-plan/public/documentation-governance-and-refresh/traces/documentation-governance-and-refresh-trace.md
index 8a3c9c33..300549ca 100644
--- a/ai-plan/public/documentation-governance-and-refresh/traces/documentation-governance-and-refresh-trace.md
+++ b/ai-plan/public/documentation-governance-and-refresh/traces/documentation-governance-and-refresh-trace.md
@@ -2,7 +2,7 @@
## 2026-04-22
-### 当前恢复点:RP-012
+### 当前恢复点:RP-013
- 本轮从 PR #268 的最新 review 数据恢复,未发现失败检查;CTRF 报告显示 2139 个测试全部通过
- 本轮复核确认当前 PR 的 latest-head open thread 同时来自 `coderabbitai[bot]` 与 `greptile-apps[bot]`
@@ -23,8 +23,11 @@
- 新页面统一收口到“包关系、最小接入路径、真实生成语义、生命周期边界、诊断约束”,不再沿用旧教程式长篇 API 罗列
- 本轮额外复核了 `ai-libs/CoreGrid` 的真实采用方式,确认 `[GetNode]` / `[BindNodeSignal]` 组合使用时应先注入节点再绑定事件
- 本轮继续收口 `auto-register-exported-collections-generator.md`,补齐 frontmatter,并把“导出集合”纠正为“实例可读集合成员 + registry 成员 + 单参数实例方法”的真实契约
-- 本轮复核 `docs/zh-CN/tutorials/godot-integration.md`,确认其中仍残留 `GetNodeX`、`AbstractGodotModule`、`InstallGodotModule`、
- `GFramework.Godot.Pool` 等旧 API / 旧模块叙述,tutorial 已成为下一轮高优先级清理对象
+- 本轮已重写 `docs/zh-CN/tutorials/godot-integration.md`,把内容收口为“包关系、`project.godot` 接线、`[GetNode]` /
+ `[BindNodeSignal]` 协作顺序、运行时扩展边界、迁移提醒”,不再把旧 Godot API 列表当事实来源
+- `docs/zh-CN/tutorials/index.md` 的 Godot 教程入口摘要已同步改成当前采用路径,避免入口页继续把教程描述成对象池 / 性能优化总览
+- 本轮检索确认 Godot 栏目仍有下一批高风险页面:`docs/zh-CN/godot/index.md` 与 `docs/zh-CN/godot/architecture.md` 还保留
+ `GetNodeX`、`CreateSignalBuilder`、`InstallGodotModule(...).Wait()` 等旧叙述,应作为 tutorial 之后的下一轮收口对象
### 当前决策
@@ -35,7 +38,8 @@
- `Godot.SourceGenerators` 专题页继续采用“源码 / 测试 / README 优先,`ai-libs/` 只补消费者 wiring”的证据顺序
- `BindNodeSignal` 页面明确记录“当前不自动生成 `_Ready()` / `_ExitTree()`”,避免继续把它写成自动生命周期织入器
- `auto-register-exported-collections` 页面明确区分“运行时 null 时跳过注册”和“配置错误时编译期报错”,避免旧文档把两类边界混为一谈
-- `godot-integration.md` 不再适合作为当前 Godot 采用路径的事实来源;后续只能把它当待修输出,而不是事实输入
+- `godot-integration.md` 已重新成为可用的采用路径入口;后续 Godot 文档收口应优先处理 `godot/index.md` 和 `godot/architecture.md`
+- `docs/zh-CN/godot/index.md` 若继续保留旧写法,会重新把 tutorial 已清掉的旧接入路径带回导航入口,因此优先级高于继续扩展新教程
### 验证
@@ -51,10 +55,12 @@
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/bind-node-signal-generator.md`
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/auto-register-exported-collections-generator.md`
- `cd docs && bun run build`
-- `rg -n "GetNodeX|AbstractGodotModule|InstallGodotModule|GodotGameArchitecture|GFramework\\.Godot\\.Pool" docs/zh-CN/tutorials/godot-integration.md`
+- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/tutorials/godot-integration.md`
+- `cd docs && bun run build`
+- `rg -n "GetNodeX|CreateSignalBuilder|GodotGameArchitecture|AbstractGodotModule|InstallGodotModule\(|GFramework\\.Godot\\.Pool" docs/zh-CN/godot docs/zh-CN/tutorials -S`
### 下一步
-1. 下一次推送后重新执行 `$gframework-pr-review`,确认 PR #268 的 CodeRabbit / Greptile open thread 是否关闭或减少
-2. 继续使用 `gframework-doc-refresh` 对 `Godot.SourceGenerators` 做真实模块扫描
-3. 优先重写或拆分 `tutorials/godot-integration.md`,先清掉已确认失真的 Godot 旧 API 与旧模块示例
+1. 优先重写 `docs/zh-CN/godot/index.md`,清掉 `GetNodeX`、`CreateSignalBuilder`、`InstallGodotModule(...)` 默认化叙述
+2. 视 `godot/index.md` 收口结果,决定是否同步压缩 `docs/zh-CN/godot/architecture.md`
+3. 下一次推送后重新执行 `$gframework-pr-review`,确认 PR #268 的 CodeRabbit / Greptile open thread 是否关闭或减少
diff --git a/docs/zh-CN/tutorials/godot-integration.md b/docs/zh-CN/tutorials/godot-integration.md
index 94f1d51c..595a5a31 100644
--- a/docs/zh-CN/tutorials/godot-integration.md
+++ b/docs/zh-CN/tutorials/godot-integration.md
@@ -1,1357 +1,275 @@
+---
+title: Godot 集成教程
+description: 以当前源码和真实消费者接线为准,说明 GFramework 在 Godot 项目中的最小接入路径、生成器协作顺序与常见迁移边界。
+---
+
# Godot 集成教程
-> 深入学习如何将 GFramework 与 Godot 引擎完美集成,创建高性能的游戏应用。
+这篇教程只讲当前仓库里仍然成立的 Godot 接入路径:
-## 📋 目录
+- 项目级配置:`project.godot` -> `AutoLoads` / `InputActions`
+- 场景级样板:`[GetNode]` / `[BindNodeSignal]`
+- 运行时辅助:节点生命周期、事件解绑、异步等待
-- [Godot 特定功能](#godot-特定功能)
-- [节点生命周期管理](#节点生命周期管理)
-- [信号系统集成](#信号系统集成)
-- [资源管理优化](#资源管理优化)
-- [性能优化技巧](#性能优化技巧)
-- [常见集成模式](#常见集成模式)
-- [调试与测试](#调试与测试)
+它不再把旧版长篇 API 列表当事实来源,也不把 `AbstractGodotModule` / `InstallGodotModule(...)` 当成默认接入起点。
-## Godot 特定功能
+## 先认清包关系
-### 0. project.godot 编译期接入
+一个常见的 Godot + GFramework 项目,通常会同时用到这几层:
-如果项目引用了 `GFramework.Godot.SourceGenerators`,现在可以直接把 `project.godot` 中的 AutoLoad 与 Input Action 暴露为强类型
-API:
+- `GeWuYou.GFramework`:聚合包,提供 Core / Game 常用能力
+- `GeWuYou.GFramework.Godot`:Godot 运行时扩展,例如节点生命周期辅助、`UnRegisterWhenNodeExitTree`、`WaitUntilReadyAsync`
+- `GeWuYou.GFramework.Core.SourceGenerators`:`[ContextAware]`、`[GetSystem]`、`[GetModel]` 等 Core 侧生成器
+- `GeWuYou.GFramework.Godot.SourceGenerators`:`[GetNode]`、`[BindNodeSignal]`、`project.godot` 元数据生成器
+
+如果你只装运行时包,没有装生成器包,那么 `[GetNode]`、`[BindNodeSignal]`、`AutoLoads`、`InputActions` 都不会出现。
+
+## 第一步:接好项目级配置
+
+### 安装包
+
+```bash
+dotnet add package GeWuYou.GFramework
+dotnet add package GeWuYou.GFramework.Godot
+dotnet add package GeWuYou.GFramework.Core.SourceGenerators
+dotnet add package GeWuYou.GFramework.Godot.SourceGenerators
+```
+
+`GeWuYou.GFramework.Godot.SourceGenerators` 作为 NuGet 包使用时,会自动把项目根目录下的 `project.godot` 加入
+`AdditionalFiles`。
+
+### 什么时候需要手动加 `AdditionalFiles`
+
+只有在仓库内直接用 analyzer 方式引用生成器项目时,才需要手动补:
+
+```xml
+
+
+
+
+```
+
+### 可以改路径,不能改文件名
+
+如果你的 `project.godot` 不在项目根目录,可以改相对路径:
+
+```xml
+
+ Config/project.godot
+
+```
+
+但文件名仍然必须是 `project.godot`。当前 `targets` 和生成器都会按这个文件名识别输入。
+
+## 第二步:把架构和 Godot 节点分开看
+
+当前真实消费者 `ai-libs/CoreGrid` 的默认接入方式,是:
+
+- 架构层继续用常规 `InstallModule(new SomeModule())`
+- Godot 节点脚本通过运行时扩展和源码生成器接入场景
+
+也就是说,Godot 集成的主体并不是“所有东西都塞进 Godot 模块”,而是“架构注册”和“场景节点接线”各自负责自己的边界。
+
+一个最小架构可以长这样:
+
+```csharp
+using GFramework.Core.Abstractions.Architectures;
+using GFramework.Core.Abstractions.Environment;
+using GFramework.Godot.Architectures;
+
+namespace MyGame.Scripts.Core;
+
+public sealed class GameArchitecture(
+ IArchitectureConfiguration configuration,
+ IEnvironment environment)
+ : AbstractArchitecture(configuration, environment)
+{
+ protected override void InstallModules()
+ {
+ InstallModule(new UtilityModule());
+ InstallModule(new ModelModule());
+ InstallModule(new GameplayModule());
+ InstallModule(new SystemModule());
+ }
+}
+```
+
+这里选择 `AbstractArchitecture`,是为了让架构生命周期能挂到 Godot 场景树;但模块注册本身仍然是普通的
+`InstallModule(...)`。
+
+## 第三步:把 `project.godot` 变成强类型入口
+
+`GFramework.Godot.SourceGenerators` 会读取 `project.godot` 的两个段:
+
+- `[autoload]` -> `GFramework.Godot.Generated.AutoLoads`
+- `[input]` -> `GFramework.Godot.Generated.InputActions`
+
+例如:
+
+```ini
+[autoload]
+GameServices="*res://autoload/game_services.tscn"
+
+[input]
+ui_cancel={
+}
+move_up={
+}
+```
+
+就可以在 C# 里直接使用:
```csharp
using GFramework.Godot.Generated;
+using Godot;
-var services = AutoLoads.GameServices;
+if (AutoLoads.TryGetGameServices(out var gameServices))
+{
+}
-if (Input.IsActionPressed(InputActions.MoveUp))
+if (Input.IsActionJustPressed(InputActions.UiCancel))
{
}
```
-这项能力适合和 `[GetNode]`、`[BindNodeSignal]` 一起使用:前者解决项目级配置入口,后两者解决场景级节点和事件样板。
+这部分只解决“项目级配置入口”,不会处理场景里的节点查找或事件绑定。
-详细说明见:[Godot 项目元数据生成器](../source-generators/godot-project-generator)
+## 第四步:把场景节点样板交给生成器
-### 1. 节点生命周期绑定
-
-GFramework.Godot 提供了与 Godot 节点生命周期的无缝集成,确保框架初始化与 Godot 场景树同步。
+当前最稳定的场景级接入方式,是让 `[GetNode]` 负责节点字段注入,让 `[BindNodeSignal]` 负责 CLR event 订阅。
```csharp
-using GFramework.Godot.Architecture;
+using GFramework.Godot.SourceGenerators.Abstractions;
+using Godot;
-public class GodotGameArchitecture : AbstractArchitecture
+namespace MyGame.Scripts.Ui;
+
+public partial class MainMenu : Control
{
- protected override void Init()
- {
- // 注册核心组件
- RegisterModel(new PlayerModel());
- RegisterSystem(new PlayerControllerSystem());
- RegisterUtility(new AudioUtility());
- }
-
- protected override void InstallModules()
- {
- // 安装 Godot 特定模块
- InstallGodotModule(new AudioModule());
- InstallGodotModule(new InputModule());
- }
-}
-```
+ [GetNode]
+ private Button _startButton = null!;
-### 2. Godot 模块系统
+ [GetNode]
+ private Button _quitButton = null!;
-创建与 Godot 节点深度集成的模块:
-
-```csharp
-[ContextAware]
-[Log]
-public partial class AudioModule : AbstractGodotModule
-{
- private AudioStreamPlayer _musicPlayer;
- private AudioStreamPlayer _sfxPlayer;
-
- // 模块节点本身
- public override Node Node => this;
-
- public override void Install(IArchitecture architecture)
- {
- // 注册音频系统
- architecture.RegisterSystem(new AudioSystem());
- architecture.RegisterUtility(new AudioUtility());
- }
-
- public override void OnAttach(Architecture architecture)
- {
- // 模块附加时的初始化
- Logger.Info("Audio module attached");
-
- // 创建音频播放器
- CreateAudioPlayers();
- }
-
- public override void OnDetach(Architecture architecture)
- {
- // 模块分离时的清理
- Logger.Info("Audio module detached");
- CleanupAudioPlayers();
- }
-
- public override void OnPhase(ArchitecturePhase phase, IArchitecture architecture)
- {
- switch (phase)
- {
- case ArchitecturePhase.Ready:
- // 架构准备就绪,开始播放背景音乐
- PlayBackgroundMusic();
- break;
- }
- }
-
- private void CreateAudioPlayers()
- {
- _musicPlayer = new AudioStreamPlayer();
- AddChild(_musicPlayer);
-
- _sfxPlayer = new AudioStreamPlayer();
- AddChild(_sfxPlayer);
- }
-
- private void CleanupAudioPlayers()
- {
- _musicPlayer?.QueueFree();
- _sfxPlayer?.QueueFree();
- }
-
- private void PlayBackgroundMusic()
- {
- var music = GD.Load("res://assets/audio/background.ogg");
- _musicPlayer.Stream = music;
- _musicPlayer.Play();
- }
-}
-```
-
-### 3. 节点池化系统
-
-实现高效的 Godot 节点池化,避免频繁的创建和销毁:
-
-```csharp
-using GFramework.Godot.Pool;
-
-public class BulletPoolSystem : AbstractNodePoolSystem
-{
- private Dictionary _scenes = new();
-
- public BulletPoolSystem()
- {
- // 预加载场景
- _scenes["player"] = GD.Load("res://assets/scenes/PlayerBullet.tscn");
- _scenes["enemy"] = GD.Load("res://assets/scenes/EnemyBullet.tscn");
- }
-
- protected override Bullet CreateItem(string key)
- {
- if (_scenes.TryGetValue(key, out var scene))
- {
- return scene.Instantiate();
- }
-
- throw new ArgumentException($"Unknown bullet type: {key}");
- }
-
- protected override void OnSpawn(Bullet item, string key)
- {
- // 重置子弹状态
- item.Reset();
- item.Position = Vector2.Zero;
- item.Visible = true;
- item.SetCollisionLayerValue(1, true);
- item.SetCollisionMaskValue(1, true);
- }
-
- protected override void OnDespawn(Bullet item)
- {
- // 隐藏子弹
- item.Visible = false;
- item.SetCollisionLayerValue(1, false);
- item.SetCollisionMaskValue(1, false);
-
- // 移除父节点
- item.GetParent()?.RemoveChild(item);
- }
-
- protected override bool CanDespawn(Bullet item)
- {
- // 只有不在使用中的子弹才能回收
- return !item.IsActive && item.GetParent() != null;
- }
-}
-```
-
-## 节点生命周期管理
-
-### 1. 自动生命周期绑定
-
-使用 GFramework 的扩展方法自动管理节点生命周期:
-
-```csharp
-[ContextAware]
-[Log]
-public partial class PlayerController : CharacterBody2D, IController
-{
- private PlayerModel _playerModel;
-
public override void _Ready()
{
- // 设置上下文
- _playerModel = this.GetModel();
-
- // 注册事件监听,自动与节点生命周期绑定
- this.RegisterEvent(OnPlayerInput)
- .UnRegisterWhenNodeExitTree(this);
-
- // 监听属性变化,自动清理
- _playerModel.Health.Register(OnHealthChanged)
- .UnRegisterWhenNodeExitTree(this);
-
- // 连接 Godot 信号,自动清理
- this.CreateSignalBuilder(AnimationPlayer.SignalName.AnimationFinished)
- .Connect(OnAnimationFinished)
- .UnRegisterWhenNodeExitTree(this);
+ __InjectGetNodes_Generated();
+ __BindNodeSignals_Generated();
}
-
- private void OnPlayerInput(PlayerInputEvent e)
- {
- // 处理玩家输入
- ProcessInput(e);
- }
-
- private void OnHealthChanged(int newHealth)
- {
- // 更新 UI 显示
- UpdateHealthDisplay(newHealth);
-
- // 播放受伤动画
- if (newHealth < _playerModel.PreviousHealth)
- {
- AnimationPlayer.Play("hurt");
- }
- }
-
- private void OnAnimationFinished(StringName animName)
- {
- if (animName == "hurt")
- {
- AnimationPlayer.Play("idle");
- }
- }
-}
-```
-### 2. 延迟初始化模式
-
-对于需要在特定时机初始化的组件:
-
-```csharp
-[ContextAware]
-[Log]
-public partial class AdvancedController : Node, IController
-{
- private bool _initialized = false;
-
- public override void _Ready()
- {
- // 不立即初始化,等待特定条件
- this.WaitUntil(() => IsInitializationReady())
- .Then(InitializeController);
- }
-
- private bool IsInitializationReady()
- {
- // 检查所有依赖是否准备就绪
- return HasRequiredComponents() && Context.HasModel();
- }
-
- private void InitializeController()
- {
- if (_initialized) return;
-
- Logger.Info("Initializing advanced controller");
-
- // 执行初始化逻辑
- SetupComponents();
- RegisterEventListeners();
- StartUpdateLoop();
-
- _initialized = true;
- }
-
- private void SetupComponents()
- {
- // 设置组件
- }
-
- private void RegisterEventListeners()
- {
- // 注册事件监听器
- this.RegisterEvent(OnGameStateChanged)
- .UnRegisterWhenNodeExitTree(this);
- }
-
- private void StartUpdateLoop()
- {
- // 启动更新循环
- SetProcess(true);
- }
-}
-```
-
-### 3. 安全的节点操作
-
-使用 GFramework 提供的安全扩展方法:
-
-```csharp
-public partial class SafeNodeOperations : Node
-{
- public void SafeOperations()
- {
- // 安全获取子节点
- var player = GetNodeX("Player");
- var ui = FindChildX("UI");
-
- // 安全添加子节点
- var bullet = bulletScene.Instantiate();
- AddChildX(bullet);
-
- // 安全的异步操作
- this.WaitUntilReadyAsync()
- .Then(() => {
- // 节点准备就绪后的操作
- InitializeAfterReady();
- });
-
- // 安全的场景树遍历
- this.ForEachChild(child => {
- if (child is Sprite2D sprite)
- {
- ProcessSprite(sprite);
- }
- });
- }
-
- private void ProcessSprite(Sprite2D sprite)
- {
- // 处理精灵
- }
-
- private void InitializeAfterReady()
- {
- // 初始化逻辑
- }
-}
-```
-
-## 信号系统集成
-
-### 1. SignalBuilder 流畅 API
-
-使用 GFramework 的 SignalBuilder 进行类型安全的信号连接:
-
-```csharp
-[ContextAware]
-[Log]
-public partial class SignalController : Node, IController
-{
- private Button _button;
- private Timer _timer;
- private ProgressBar _progressBar;
-
- public override void _Ready()
- {
- InitializeComponents();
- SetupSignalConnections();
- }
-
- private void InitializeComponents()
- {
- _button = GetNode