diff --git a/docs/zh-CN/source-generators/bind-node-signal-generator.md b/docs/zh-CN/source-generators/bind-node-signal-generator.md
new file mode 100644
index 0000000..9a10631
--- /dev/null
+++ b/docs/zh-CN/source-generators/bind-node-signal-generator.md
@@ -0,0 +1,680 @@
+# BindNodeSignal 生成器
+
+> 自动生成 Godot 节点信号绑定与解绑逻辑,消除事件订阅样板代码
+
+## 概述
+
+BindNodeSignal 生成器为标记了 `[BindNodeSignal]` 特性的方法自动生成节点事件绑定和解绑代码。它将 `_Ready()` 和
+`_ExitTree()` 中重复的 `+=` 和 `-=` 样板代码收敛到生成器中统一维护。
+
+### 核心功能
+
+- **自动事件绑定**:在 `_Ready()` 中自动订阅节点事件
+- **自动事件解绑**:在 `_ExitTree()` 中自动取消订阅
+- **多事件绑定**:一个方法可以绑定到多个节点事件
+- **类型安全检查**:编译时验证方法签名与事件委托的兼容性
+- **与 GetNode 集成**:无缝配合 `[GetNode]` 特性使用
+
+## 基础使用
+
+### 标记事件处理方法
+
+使用 `[BindNodeSignal]` 特性标记处理节点事件的方法:
+
+```csharp
+using GFramework.Godot.SourceGenerators.Abstractions;
+using Godot;
+
+public partial class MainMenu : Control
+{
+ private Button _startButton = null!;
+ private Button _settingsButton = null!;
+ private Button _quitButton = null!;
+
+ [BindNodeSignal(nameof(_startButton), nameof(Button.Pressed))]
+ private void OnStartButtonPressed()
+ {
+ StartGame();
+ }
+
+ [BindNodeSignal(nameof(_settingsButton), nameof(Button.Pressed))]
+ private void OnSettingsButtonPressed()
+ {
+ ShowSettings();
+ }
+
+ [BindNodeSignal(nameof(_quitButton), nameof(Button.Pressed))]
+ private void OnQuitButtonPressed()
+ {
+ QuitGame();
+ }
+
+ public override void _Ready()
+ {
+ __BindNodeSignals_Generated();
+ }
+
+ public override void _ExitTree()
+ {
+ __UnbindNodeSignals_Generated();
+ }
+}
+```
+
+### 生成的代码
+
+编译器会为标记的类自动生成以下代码:
+
+```csharp
+//
+#nullable enable
+
+namespace YourNamespace;
+
+partial class MainMenu
+{
+ private void __BindNodeSignals_Generated()
+ {
+ _startButton.Pressed += OnStartButtonPressed;
+ _settingsButton.Pressed += OnSettingsButtonPressed;
+ _quitButton.Pressed += OnQuitButtonPressed;
+ }
+
+ private void __UnbindNodeSignals_Generated()
+ {
+ _startButton.Pressed -= OnStartButtonPressed;
+ _settingsButton.Pressed -= OnSettingsButtonPressed;
+ _quitButton.Pressed -= OnQuitButtonPressed;
+ }
+}
+```
+
+## 参数说明
+
+`[BindNodeSignal]` 特性需要两个参数:
+
+| 参数 | 类型 | 说明 |
+|-----------------|--------|-----------------------------|
+| `nodeFieldName` | string | 目标节点字段名(使用 `nameof` 推荐) |
+| `signalName` | string | 目标节点上的 CLR 事件名(使用 `nameof`) |
+
+```csharp
+[BindNodeSignal("_startButton", "Pressed")] // 字符串字面量
+[BindNodeSignal(nameof(_startButton), nameof(Button.Pressed))] // 推荐:nameof 表达式
+```
+
+## 高级用法
+
+### 带参数的事件处理
+
+处理带参数的事件(如 `SpinBox.ValueChanged`):
+
+```csharp
+using Godot;
+
+public partial class SettingsPanel : Control
+{
+ private SpinBox _volumeSpinBox = null!;
+ private SpinBox _brightnessSpinBox = null!;
+
+ // 参数类型必须与事件委托匹配
+ [BindNodeSignal(nameof(_volumeSpinBox), nameof(SpinBox.ValueChanged))]
+ private void OnVolumeChanged(double value)
+ {
+ SetVolume((float)value);
+ }
+
+ [BindNodeSignal(nameof(_brightnessSpinBox), nameof(SpinBox.ValueChanged))]
+ private void OnBrightnessChanged(double value)
+ {
+ SetBrightness((float)value);
+ }
+
+ public override void _Ready()
+ {
+ __BindNodeSignals_Generated();
+ }
+
+ public override void _ExitTree()
+ {
+ __UnbindNodeSignals_Generated();
+ }
+}
+```
+
+### 多事件绑定
+
+一个方法可以同时绑定到多个节点的事件:
+
+```csharp
+public partial class MultiButtonHud : Control
+{
+ private Button _buttonA = null!;
+ private Button _buttonB = null!;
+ private Button _buttonC = null!;
+
+ // 一个方法处理多个按钮的点击
+ [BindNodeSignal(nameof(_buttonA), nameof(Button.Pressed))]
+ [BindNodeSignal(nameof(_buttonB), nameof(Button.Pressed))]
+ [BindNodeSignal(nameof(_buttonC), nameof(Button.Pressed))]
+ private void OnAnyButtonPressed()
+ {
+ PlayClickSound();
+ }
+
+ public override void _Ready()
+ {
+ __BindNodeSignals_Generated();
+ }
+
+ public override void _ExitTree()
+ {
+ __UnbindNodeSignals_Generated();
+ }
+}
+```
+
+### 与 [GetNode] 组合使用
+
+推荐与 `[GetNode]` 特性结合使用:
+
+```csharp
+using GFramework.Godot.SourceGenerators.Abstractions;
+using Godot;
+
+public partial class GameHud : Control
+{
+ // 使用 GetNode 自动获取节点
+ [GetNode]
+ private Button _pauseButton = null!;
+
+ [GetNode]
+ private ProgressBar _healthBar = null!;
+
+ [GetNode("UI/ScoreLabel")]
+ private Label _scoreLabel = null!;
+
+ // 使用 BindNodeSignal 绑定事件
+ [BindNodeSignal(nameof(_pauseButton), nameof(Button.Pressed))]
+ private void OnPauseButtonPressed()
+ {
+ TogglePause();
+ }
+
+ // 多事件绑定示例
+ [BindNodeSignal(nameof(_healthBar), nameof(Range.ValueChanged))]
+ private void OnHealthChanged(double value)
+ {
+ UpdateHealthDisplay(value);
+ }
+
+ public override void _Ready()
+ {
+ // 先注入节点,再绑定信号
+ __InjectGetNodes_Generated();
+ __BindNodeSignals_Generated();
+ }
+
+ public override void _ExitTree()
+ {
+ __UnbindNodeSignals_Generated();
+ }
+}
+```
+
+### 复杂事件处理场景
+
+实现完整的 UI 事件处理:
+
+```csharp
+public partial class InventoryUI : Control
+{
+ // 节点
+ [GetNode]
+ private ItemList _itemList = null!;
+
+ [GetNode]
+ private Button _useButton = null!;
+
+ [GetNode]
+ private Button _dropButton = null!;
+
+ [GetNode]
+ private LineEdit _searchBox = null!;
+
+ // 事件处理
+ [BindNodeSignal(nameof(_itemList), nameof(ItemList.ItemSelected))]
+ private void OnItemSelected(long index)
+ {
+ SelectItem((int)index);
+ }
+
+ [BindNodeSignal(nameof(_itemList), nameof(ItemList.ItemActivated))]
+ private void OnItemActivated(long index)
+ {
+ UseItem((int)index);
+ }
+
+ [BindNodeSignal(nameof(_useButton), nameof(Button.Pressed))]
+ private void OnUseButtonPressed()
+ {
+ UseSelectedItem();
+ }
+
+ [BindNodeSignal(nameof(_dropButton), nameof(Button.Pressed))]
+ private void OnDropButtonPressed()
+ {
+ DropSelectedItem();
+ }
+
+ [BindNodeSignal(nameof(_searchBox), nameof(LineEdit.TextChanged))]
+ private void OnSearchTextChanged(string newText)
+ {
+ FilterItems(newText);
+ }
+
+ public override void _Ready()
+ {
+ __InjectGetNodes_Generated();
+ __BindNodeSignals_Generated();
+ InitializeInventory();
+ }
+
+ public override void _ExitTree()
+ {
+ __UnbindNodeSignals_Generated();
+ }
+}
+```
+
+## 生命周期管理
+
+### 自动生成生命周期方法
+
+如果类没有 `_Ready()` 或 `_ExitTree()`,生成器会自动生成:
+
+```csharp
+public partial class AutoLifecycleHud : Control
+{
+ private Button _button = null!;
+
+ [BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+ private void OnButtonPressed()
+ {
+ // 处理点击
+ }
+
+ // 无需手动声明 _Ready 和 _ExitTree
+ // 生成器会自动生成:
+ // public override void _Ready() { __BindNodeSignals_Generated(); }
+ // public override void _ExitTree() { __UnbindNodeSignals_Generated(); }
+}
+```
+
+### 手动生命周期调用
+
+如果已有生命周期方法,需要手动调用生成的方法:
+
+```csharp
+public partial class CustomLifecycleHud : Control
+{
+ private Button _button = null!;
+
+ [BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+ private void OnButtonPressed()
+ {
+ HandlePress();
+ }
+
+ public override void _Ready()
+ {
+ // 必须手动调用绑定方法
+ __BindNodeSignals_Generated();
+
+ // 自定义初始化逻辑
+ InitializeUI();
+ }
+
+ public override void _ExitTree()
+ {
+ // 必须手动调用解绑方法
+ __UnbindNodeSignals_Generated();
+
+ // 自定义清理逻辑
+ CleanupResources();
+ }
+}
+```
+
+**注意**:如果在 `_Ready()` 中不调用 `__BindNodeSignals_Generated()`,编译器会发出警告 `GF_Godot_BindNodeSignal_008`。
+
+## 诊断信息
+
+生成器会在以下情况报告编译错误或警告:
+
+### GF_Godot_BindNodeSignal_001 - 不支持嵌套类
+
+**错误信息**:`Class '{ClassName}' cannot use [BindNodeSignal] inside a nested type`
+
+**解决方案**:将嵌套类提取为独立的类
+
+```csharp
+// ❌ 错误
+public partial class Outer
+{
+ public partial class Inner
+ {
+ [BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+ private void OnPressed() { } // 错误
+ }
+}
+
+// ✅ 正确
+public partial class Inner
+{
+ [BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+ private void OnPressed() { }
+}
+```
+
+### GF_Godot_BindNodeSignal_002 - 不支持静态方法
+
+**错误信息**:`Method '{MethodName}' cannot be static when using [BindNodeSignal]`
+
+**解决方案**:改为实例方法
+
+```csharp
+// ❌ 错误
+[BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+private static void OnPressed() { }
+
+// ✅ 正确
+[BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+private void OnPressed() { }
+```
+
+### GF_Godot_BindNodeSignal_003 - 节点字段不存在
+
+**错误信息**:
+`Method '{MethodName}' references node field '{FieldName}', but no matching field exists on class '{ClassName}'`
+
+**解决方案**:确保引用的字段存在且名称正确
+
+```csharp
+// ❌ 错误:_button 字段不存在
+[BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+private void OnPressed() { }
+
+// ✅ 正确
+private Button _button = null!;
+
+[BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+private void OnPressed() { }
+```
+
+### GF_Godot_BindNodeSignal_004 - 节点字段必须是实例字段
+
+**错误信息**:`Method '{MethodName}' references node field '{FieldName}', but that field must be an instance field`
+
+**解决方案**:将节点字段改为实例字段(非静态)
+
+```csharp
+// ❌ 错误
+private static Button _button = null!;
+
+// ✅ 正确
+private Button _button = null!;
+```
+
+### GF_Godot_BindNodeSignal_005 - 字段类型必须继承自 Godot.Node
+
+**错误信息**:`Field '{FieldName}' must be a Godot.Node type to use [BindNodeSignal]`
+
+**解决方案**:确保字段类型继承自 `Godot.Node`
+
+```csharp
+// ❌ 错误
+private string _text = null!; // string 不是 Node 类型
+
+[BindNodeSignal(nameof(_text), "Changed")] // 错误
+
+// ✅ 正确
+private Button _button = null!; // Button 继承自 Node
+
+[BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+```
+
+### GF_Godot_BindNodeSignal_006 - 目标事件不存在
+
+**错误信息**:`Field '{FieldName}' does not contain an event named '{EventName}'`
+
+**解决方案**:确保事件名称正确
+
+```csharp
+private Button _button = null!;
+
+// ❌ 错误:Click 不是 Button 的事件
+[BindNodeSignal(nameof(_button), "Click")]
+
+// ✅ 正确:使用正确的事件名
+[BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+```
+
+### GF_Godot_BindNodeSignal_007 - 方法签名不兼容
+
+**错误信息**:`Method '{MethodName}' is not compatible with event '{EventName}' on field '{FieldName}'`
+
+**解决方案**:确保方法签名与事件委托匹配
+
+```csharp
+private SpinBox _spinBox = null!;
+
+// ❌ 错误:SpinBox.ValueChanged 需要 double 参数
+[BindNodeSignal(nameof(_spinBox), nameof(SpinBox.ValueChanged))]
+private void OnValueChanged() { } // 缺少参数
+
+// ✅ 正确
+[BindNodeSignal(nameof(_spinBox), nameof(SpinBox.ValueChanged))]
+private void OnValueChanged(double value) { }
+```
+
+### GF_Godot_BindNodeSignal_008 - 需要在 _Ready 中调用绑定方法
+
+**警告信息**:
+`Class '{ClassName}' defines _Ready(); call __BindNodeSignals_Generated() there to bind [BindNodeSignal] handlers`
+
+**解决方案**:在 `_Ready()` 中手动调用 `__BindNodeSignals_Generated()`
+
+```csharp
+public override void _Ready()
+{
+ __BindNodeSignals_Generated(); // ✅ 必须手动调用
+ // 其他初始化...
+}
+```
+
+### GF_Godot_BindNodeSignal_009 - 需要在 _ExitTree 中调用解绑方法
+
+**警告信息**:
+`Class '{ClassName}' defines _ExitTree(); call __UnbindNodeSignals_Generated() there to unbind [BindNodeSignal] handlers`
+
+**解决方案**:在 `_ExitTree()` 中手动调用 `__UnbindNodeSignals_Generated()`
+
+```csharp
+public override void _ExitTree()
+{
+ __UnbindNodeSignals_Generated(); // ✅ 必须手动调用
+ // 其他清理...
+}
+```
+
+### GF_Godot_BindNodeSignal_010 - 构造参数无效
+
+**错误信息**:
+`Method '{MethodName}' uses [BindNodeSignal] with an invalid '{ParameterName}' constructor argument; it must be a non-empty string literal`
+
+**解决方案**:使用有效的字符串字面量或 nameof 表达式
+
+```csharp
+// ❌ 错误:空字符串
+[BindNodeSignal("", nameof(Button.Pressed))]
+
+// ❌ 错误:null 值
+[BindNodeSignal(null, nameof(Button.Pressed))]
+
+// ✅ 正确
+[BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+```
+
+## 最佳实践
+
+### 1. 使用 nameof 表达式
+
+使用 `nameof` 而不是字符串字面量,以获得重构支持和编译时检查:
+
+```csharp
+// ❌ 不推荐:字符串字面量
+[BindNodeSignal("_button", "Pressed")]
+
+// ✅ 推荐:nameof 表达式
+[BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+```
+
+### 2. 保持方法命名一致
+
+使用统一的命名约定提高代码可读性:
+
+```csharp
+// ✅ 推荐:On + 节点名 + 事件名
+[BindNodeSignal(nameof(_startButton), nameof(Button.Pressed))]
+private void OnStartButtonPressed() { }
+
+[BindNodeSignal(nameof(_volumeSlider), nameof(Slider.ValueChanged))]
+private void OnVolumeSliderValueChanged(double value) { }
+```
+
+### 3. 分组相关事件处理
+
+将相关的事件处理方法放在一起,便于维护:
+
+```csharp
+public partial class GameHud : Control
+{
+ // UI 节点
+ [GetNode]
+ private Button _pauseButton = null!;
+
+ [GetNode]
+ private Button _menuButton = null!;
+
+ // UI 事件处理(放在一起)
+ [BindNodeSignal(nameof(_pauseButton), nameof(Button.Pressed))]
+ private void OnPauseButtonPressed() { }
+
+ [BindNodeSignal(nameof(_menuButton), nameof(Button.Pressed))]
+ private void OnMenuButtonPressed() { }
+}
+```
+
+### 4. 正确处理生命周期
+
+始终确保事件解绑,避免内存泄漏:
+
+```csharp
+public partial class SafeHud : Control
+{
+ private Button _button = null!;
+
+ [BindNodeSignal(nameof(_button), nameof(Button.Pressed))]
+ private void OnButtonPressed() { }
+
+ public override void _Ready()
+ {
+ __BindNodeSignals_Generated();
+ }
+
+ public override void _ExitTree()
+ {
+ // 确保解绑事件
+ __UnbindNodeSignals_Generated();
+ }
+}
+```
+
+### 5. 对比手动事件绑定
+
+| 方式 | 代码量 | 可维护性 | 错误风险 | 推荐场景 |
+|--------------------|-----|------|----------|------------|
+| 手动 `+=` / `-=` | 多 | 中 | 高(易遗漏解绑) | 简单场景 |
+| `[BindNodeSignal]` | 少 | 高 | 低(编译器检查) | 复杂 UI、频繁事件 |
+
+```csharp
+// ❌ 不推荐:手动绑定
+public override void _Ready()
+{
+ _startButton.Pressed += OnStartButtonPressed;
+ _settingsButton.Pressed += OnSettingsButtonPressed;
+ _quitButton.Pressed += OnQuitButtonPressed;
+}
+
+public override void _ExitTree()
+{
+ // 容易遗漏解绑
+ _startButton.Pressed -= OnStartButtonPressed;
+ _quitButton.Pressed -= OnQuitButtonPressed; // 遗漏了 _settingsButton
+}
+
+// ✅ 推荐:使用 [BindNodeSignal]
+[BindNodeSignal(nameof(_startButton), nameof(Button.Pressed))]
+private void OnStartButtonPressed() { }
+
+[BindNodeSignal(nameof(_settingsButton), nameof(Button.Pressed))]
+private void OnSettingsButtonPressed() { }
+
+[BindNodeSignal(nameof(_quitButton), nameof(Button.Pressed))]
+private void OnQuitButtonPressed() { }
+```
+
+### 6. 与 [ContextAware] 组合使用
+
+在需要架构访问的场景中,与 `[ContextAware]` 结合:
+
+```csharp
+using GFramework.SourceGenerators.Abstractions.Rule;
+using GFramework.Godot.SourceGenerators.Abstractions;
+
+[ContextAware]
+public partial class GameController : Node
+{
+ [GetNode]
+ private Button _actionButton = null!;
+
+ private IGameModel _gameModel = null!;
+
+ [BindNodeSignal(nameof(_actionButton), nameof(Button.Pressed))]
+ private void OnActionButtonPressed()
+ {
+ // 可以直接使用架构功能
+ this.SendCommand(new PlayerActionCommand());
+ }
+
+ public override void _Ready()
+ {
+ __InjectContextBindings_Generated();
+ __InjectGetNodes_Generated();
+ __BindNodeSignals_Generated();
+ }
+
+ public override void _ExitTree()
+ {
+ __UnbindNodeSignals_Generated();
+ }
+}
+```
+
+## 相关文档
+
+- [Source Generators 概述](./index)
+- [GetNode 生成器](./get-node-generator)
+- [ContextAware 生成器](./context-aware-generator)
+- [Godot 信号文档](https://docs.godotengine.org/en/stable/classes/class_signal.html)
diff --git a/docs/zh-CN/source-generators/get-node-generator.md b/docs/zh-CN/source-generators/get-node-generator.md
new file mode 100644
index 0000000..9c7c9e6
--- /dev/null
+++ b/docs/zh-CN/source-generators/get-node-generator.md
@@ -0,0 +1,496 @@
+# GetNode 生成器
+
+> 自动生成 Godot 节点获取逻辑,简化节点引用代码
+
+## 概述
+
+GetNode 生成器为标记了 `[GetNode]` 特性的字段自动生成 Godot 节点获取代码,无需手动调用 `GetNode()` 方法。这在处理复杂
+UI 或场景树结构时特别有用。
+
+### 核心功能
+
+- **自动节点获取**:根据路径或字段名自动获取节点
+- **多种查找模式**:支持唯一名、相对路径、绝对路径查找
+- **可选节点支持**:可以标记节点为可选,获取失败时返回 null
+- **智能路径推导**:未显式指定路径时自动从字段名推导
+- **_Ready 钩子生成**:自动生成 `_Ready()` 方法注入节点获取逻辑
+
+## 基础使用
+
+### 标记节点字段
+
+使用 `[GetNode]` 特性标记需要自动获取的节点字段:
+
+```csharp
+using GFramework.Godot.SourceGenerators.Abstractions;
+using Godot;
+
+public partial class PlayerHud : Control
+{
+ [GetNode]
+ private Label _healthLabel = null!;
+
+ [GetNode]
+ private ProgressBar _manaBar = null!;
+
+ [GetNode("ScoreContainer/ScoreValue")]
+ private Label _scoreLabel = null!;
+
+ public override void _Ready()
+ {
+ __InjectGetNodes_Generated();
+ _healthLabel.Text = "100";
+ }
+}
+```
+
+### 生成的代码
+
+编译器会为标记的类自动生成以下代码:
+
+```csharp
+//
+#nullable enable
+
+namespace YourNamespace;
+
+partial class PlayerHud
+{
+ private void __InjectGetNodes_Generated()
+ {
+ _healthLabel = GetNode("%HealthLabel");
+ _manaBar = GetNode("%ManaBar");
+ _scoreLabel = GetNode("ScoreContainer/ScoreValue");
+ }
+
+ partial void OnGetNodeReadyGenerated();
+
+ public override void _Ready()
+ {
+ __InjectGetNodes_Generated();
+ OnGetNodeReadyGenerated();
+ }
+}
+```
+
+## 配置选项
+
+### 节点查找模式
+
+通过 `Lookup` 参数控制节点查找方式:
+
+```csharp
+public partial class GameHud : Control
+{
+ // 自动推断(默认):根据路径前缀自动选择
+ [GetNode]
+ private Label _titleLabel = null!; // 默认使用唯一名 %TitleLabel
+
+ // 唯一名查找
+ [GetNode(Lookup = NodeLookupMode.UniqueName)]
+ private Button _startButton = null!; // %StartButton
+
+ // 相对路径查找
+ [GetNode("UI/HealthBar", Lookup = NodeLookupMode.RelativePath)]
+ private ProgressBar _healthBar = null!;
+
+ // 绝对路径查找
+ [GetNode("/root/Main/GameUI/Score", Lookup = NodeLookupMode.AbsolutePath)]
+ private Label _scoreLabel = null!;
+}
+```
+
+### 查找模式说明
+
+| 模式 | 路径前缀 | 适用场景 |
+|----------------|------|----------------|
+| `Auto` | 自动选择 | 默认行为,推荐用于大多数场景 |
+| `UniqueName` | `%` | 场景中使用唯一名的节点 |
+| `RelativePath` | 无 | 需要相对路径查找的节点 |
+| `AbsolutePath` | `/` | 场景树根节点的绝对路径 |
+
+### 可选节点
+
+对于可能不存在的节点,可以设置为非必填:
+
+```csharp
+public partial class SettingsPanel : Control
+{
+ // 必须存在的节点(默认)
+ [GetNode]
+ private Label _titleLabel = null!;
+
+ // 可选节点,可能不存在
+ [GetNode(Required = false)]
+ private Label? _debugLabel; // 使用可空类型
+
+ // 显式路径的可选节点
+ [GetNode("AdvancedOptions", Required = false)]
+ private VBoxContainer? _advancedOptions;
+
+ public override void _Ready()
+ {
+ __InjectGetNodes_Generated();
+
+ // 安全地访问可选节点
+ _debugLabel?.Hide();
+ _advancedOptions?.Hide();
+ }
+}
+```
+
+### 路径规则
+
+生成器根据字段名和配置自动推导节点路径:
+
+```csharp
+public partial class Example : Control
+{
+ // 驼峰命名 → PascalCase 路径
+ [GetNode]
+ private Label _playerNameLabel = null!; // → %PlayerNameLabel
+
+ // m_ 前缀会被移除
+ [GetNode]
+ private Button m_confirmButton = null!; // → %ConfirmButton
+
+ // _ 前缀会被移除
+ [GetNode]
+ private ProgressBar _healthBar = null!; // → %HealthBar
+
+ // 显式路径优先于推导
+ [GetNode("UI/CustomPath")]
+ private Label _myLabel = null!; // → UI/CustomPath
+}
+```
+
+## 高级用法
+
+### 与 [ContextAware] 组合使用
+
+在 Godot 项目中结合使用 `[GetNode]` 和 `[ContextAware]`:
+
+```csharp
+using GFramework.Godot.SourceGenerators.Abstractions;
+using GFramework.SourceGenerators.Abstractions.Rule;
+using Godot;
+
+[ContextAware]
+public partial class GameController : Node
+{
+ [GetNode]
+ private Label _scoreLabel = null!;
+
+ [GetNode("HUD/HealthBar")]
+ private ProgressBar _healthBar = null!;
+
+ private IGameModel _gameModel = null!;
+
+ public override void _Ready()
+ {
+ __InjectContextBindings_Generated(); // ContextAware 生成
+ __InjectGetNodes_Generated(); // GetNode 生成
+
+ _gameModel.Score.Register(OnScoreChanged);
+ }
+
+ private void OnScoreChanged(int newScore)
+ {
+ _scoreLabel.Text = newScore.ToString();
+ }
+}
+```
+
+### 复杂 UI 场景
+
+处理复杂的嵌套 UI 结构:
+
+```csharp
+public partial class InventoryUI : Control
+{
+ // 主容器
+ [GetNode]
+ private GridContainer _itemGrid = null!;
+
+ // 详细信息面板
+ [GetNode("DetailsPanel/ItemName")]
+ private Label _itemNameLabel = null!;
+
+ [GetNode("DetailsPanel/ItemDescription")]
+ private RichTextLabel _itemDescription = null!;
+
+ // 操作按钮
+ [GetNode("Actions/UseButton")]
+ private Button _useButton = null!;
+
+ [GetNode("Actions/DropButton")]
+ private Button _dropButton = null!;
+
+ // 可选的统计信息
+ [GetNode("DetailsPanel/Stats", Required = false)]
+ private VBoxContainer? _statsContainer;
+
+ public override void _Ready()
+ {
+ __InjectGetNodes_Generated();
+
+ // 使用注入的节点
+ _useButton.Pressed += OnUseButtonPressed;
+ _dropButton.Pressed += OnDropButtonPressed;
+ }
+}
+```
+
+### 手动 _Ready 调用
+
+如果类已经有 `_Ready()` 方法,需要手动调用注入方法:
+
+```csharp
+public partial class CustomHud : Control
+{
+ [GetNode]
+ private Label _statusLabel = null!;
+
+ public override void _Ready()
+ {
+ // 必须手动调用节点注入
+ __InjectGetNodes_Generated();
+
+ // 自定义初始化逻辑
+ _statusLabel.Text = "Ready";
+ InitializeOtherComponents();
+ }
+
+ partial void OnGetNodeReadyGenerated()
+ {
+ // 这个方法会被生成器调用,可以在此添加额外初始化
+ }
+}
+```
+
+**注意**:如果不手动调用 `__InjectGetNodes_Generated()`,编译器会发出警告 `GF_Godot_GetNode_006`。
+
+## 诊断信息
+
+生成器会在以下情况报告编译错误或警告:
+
+### GF_Godot_GetNode_001 - 不支持嵌套类
+
+**错误信息**:`Class '{ClassName}' cannot use [GetNode] inside a nested type`
+
+**解决方案**:将嵌套类提取为独立的类
+
+```csharp
+// ❌ 错误
+public partial class Outer
+{
+ public partial class Inner
+ {
+ [GetNode]
+ private Label _label = null!; // 错误
+ }
+}
+
+// ✅ 正确
+public partial class Inner
+{
+ [GetNode]
+ private Label _label = null!;
+}
+```
+
+### GF_Godot_GetNode_002 - 不支持静态字段
+
+**错误信息**:`Field '{FieldName}' cannot be static when using [GetNode]`
+
+**解决方案**:改为实例字段
+
+```csharp
+// ❌ 错误
+[GetNode]
+private static Label _label = null!;
+
+// ✅ 正确
+[GetNode]
+private Label _label = null!;
+```
+
+### GF_Godot_GetNode_003 - 不支持只读字段
+
+**错误信息**:`Field '{FieldName}' cannot be readonly when using [GetNode]`
+
+**解决方案**:移除 `readonly` 关键字
+
+```csharp
+// ❌ 错误
+[GetNode]
+private readonly Label _label = null!;
+
+// ✅ 正确
+[GetNode]
+private Label _label = null!;
+```
+
+### GF_Godot_GetNode_004 - 字段类型必须继承自 Godot.Node
+
+**错误信息**:`Field '{FieldName}' must be a Godot.Node type to use [GetNode]`
+
+**解决方案**:确保字段类型继承自 `Godot.Node`
+
+```csharp
+// ❌ 错误
+[GetNode]
+private string _text = null!; // string 不是 Node 类型
+
+// ✅ 正确
+[GetNode]
+private Label _label = null!; // Label 继承自 Node
+```
+
+### GF_Godot_GetNode_005 - 无法推导路径
+
+**错误信息**:`Field '{FieldName}' does not provide a path and its name cannot be converted to a node path`
+
+**解决方案**:显式指定节点路径
+
+```csharp
+// ❌ 错误:字段名无法转换为有效路径
+[GetNode]
+private Label _ = null!;
+
+// ✅ 正确
+[GetNode("UI/Label")]
+private Label _ = null!;
+```
+
+### GF_Godot_GetNode_006 - 需要在 _Ready 中调用注入方法
+
+**警告信息**:
+`Class '{ClassName}' defines _Ready(); call __InjectGetNodes_Generated() there or remove _Ready() to use the generated hook`
+
+**解决方案**:在 `_Ready()` 中手动调用 `__InjectGetNodes_Generated()`
+
+```csharp
+public partial class MyHud : Control
+{
+ [GetNode]
+ private Label _label = null!;
+
+ public override void _Ready()
+ {
+ __InjectGetNodes_Generated(); // ✅ 必须手动调用
+ // 其他初始化...
+ }
+}
+```
+
+## 最佳实践
+
+### 1. 使用一致的命名约定
+
+保持字段名与场景树中节点名的一致性:
+
+```csharp
+// ✅ 推荐:字段名与节点名一致
+[GetNode]
+private Label _healthLabel = null!; // 场景中的节点名为 HealthLabel
+
+[GetNode]
+private Button _startButton = null!; // 场景中的节点名为 StartButton
+```
+
+### 2. 优先使用唯一名查找
+
+在 Godot 编辑器中为重要节点启用唯一名(Unique Name),然后使用 `[GetNode]`:
+
+```csharp
+// Godot 场景中:%HealthBar(唯一名已启用)
+// C# 代码中:
+[GetNode]
+private ProgressBar _healthBar = null!; // 自动使用 %HealthBar
+```
+
+### 3. 合理处理可选节点
+
+对于可能不存在的节点,使用 `Required = false`:
+
+```csharp
+public partial class DynamicUI : Control
+{
+ [GetNode]
+ private Label _titleLabel = null!;
+
+ // 可选组件
+ [GetNode(Required = false)]
+ private TextureRect? _iconImage;
+
+ public override void _Ready()
+ {
+ __InjectGetNodes_Generated();
+
+ // 安全地初始化可选组件
+ if (_iconImage != null)
+ {
+ _iconImage.Texture = LoadDefaultIcon();
+ }
+ }
+}
+```
+
+### 4. 组织复杂 UI 的路径
+
+对于深层嵌套的 UI,使用显式路径:
+
+```csharp
+public partial class ComplexUI : Control
+{
+ // 使用相对路径明确表达层级关系
+ [GetNode("MainContent/Header/Title")]
+ private Label _title = null!;
+
+ [GetNode("MainContent/Body/Stats/Health")]
+ private Label _healthValue = null!;
+
+ [GetNode("MainContent/Footer/ActionButtons/Save")]
+ private Button _saveButton = null!;
+}
+```
+
+### 5. 与 GetNode 方法的对比
+
+| 方式 | 代码量 | 可维护性 | 类型安全 | 推荐场景 |
+|----------------|-----|------|--------|-----------|
+| 手动 `GetNode()` | 多 | 中 | 需要显式转换 | 简单场景 |
+| `[GetNode]` 特性 | 少 | 高 | 编译时检查 | 复杂 UI、控制器 |
+
+```csharp
+// ❌ 不推荐:手动获取
+public override void _Ready()
+{
+ _healthLabel = GetNode