# GFramework.Godot API 参考 > GFramework.Godot 模块的完整 API 参考文档,包含 Godot 特定扩展和集成的详细说明。 ## 📋 目录 - [架构集成](#架构集成) - [Node 扩展方法](#node-扩展方法) - [信号系统](#信号系统) - [节点池化](#节点池化) - [资源管理](#资源管理) - [日志系统](#日志系统) - [池化管理](#池化管理) - [音频系统](#音频系统) ## 架构集成 ### AbstractArchitecture Godot 特定的架构基类,继承自 Core.Architecture。 #### 新增方法 ```csharp // Godot 模块安装 protected void InstallGodotModule(IGodotModule module); protected void InstallGodotModule() where T : IGodotModule, new(); ``` #### 使用示例 ```csharp public class GameArchitecture : AbstractArchitecture { protected override void Init() { RegisterModel(new PlayerModel()); RegisterSystem(new CombatSystem()); RegisterUtility(new StorageUtility()); } protected override void InstallModules() { InstallGodotModule(new AudioModule()); InstallGodotModule(new InputModule()); } } ``` ### IGodotModule Godot 模块接口,继承自 IArchitectureModule。 #### 属性 ```csharp Node Node { get; } ``` #### 方法 ```csharp void Install(IArchitecture architecture); void OnAttach(Architecture architecture); void OnDetach(Architecture architecture); void OnPhase(ArchitecturePhase phase, IArchitecture architecture); ``` #### 使用示例 ```csharp public class AudioModule : AbstractGodotModule { // 模块节点本身 public override Node Node => this; private AudioStreamPlayer _musicPlayer; public override void Install(IArchitecture architecture) { // 注册音频系统 architecture.RegisterSystem(new AudioSystem()); architecture.RegisterUtility(new AudioUtility()); } public override void OnAttach(Architecture architecture) { // 创建音频播放器 _musicPlayer = new AudioStreamPlayer(); AddChild(_musicPlayer); Logger.Info("Audio module attached"); } public override void OnDetach(Architecture architecture) { // 清理音频播放器 _musicPlayer?.QueueFree(); Logger.Info("Audio module detached"); } public override void OnPhase(ArchitecturePhase phase, IArchitecture architecture) { switch (phase) { case ArchitecturePhase.Ready: PlayBackgroundMusic(); break; } } private void PlayBackgroundMusic() { var music = GD.Load("res://audio/background.ogg"); _musicPlayer.Stream = music; _musicPlayer.Play(); } } ``` ### AbstractGodotModule Godot 模块抽象基类,实现了 IGodotModule 接口。 #### 使用示例 ```csharp [ContextAware] [Log] public partial class SaveModule : AbstractGodotModule { private Timer _autoSaveTimer; public override void Install(IArchitecture architecture) { architecture.RegisterSystem(new SaveSystem()); architecture.RegisterUtility(new SaveUtility()); } public override void OnAttach(Architecture architecture) { // 创建自动保存计时器 _autoSaveTimer = new Timer(); _autoSaveTimer.WaitTime = 300; // 5分钟 _autoSaveTimer.Timeout += OnAutoSave; AddChild(_autoSaveTimer); _autoSaveTimer.Start(); Logger.Info("Save module attached with auto-save enabled"); } private void OnAutoSave() { var saveSystem = Context.GetSystem(); saveSystem.SaveGame("autosave"); Logger.Debug("Auto-save completed"); } } ``` ## Node 扩展方法 ### 安全节点获取 #### GetNodeX() 安全获取子节点,自动类型转换和 null 检查。 ```csharp public static T GetNodeX(this Node node, string path) where T : class; ``` #### 使用示例 ```csharp // 安全获取节点 var player = GetNodeX("Player"); var healthBar = GetNodeX("UI/HealthBar"); // 如果节点不存在或类型不匹配,会抛出异常 // 使用时不需要额外的 null 检查 ``` #### GetChildX() 安全查找子节点,支持递归查找。 ```csharp public static T GetChildX(this Node node, string path) where T : class; ``` #### 使用示例 ```csharp // 递归查找子节点 var player = FindChildX("Player"); var sprite = FindChildX("Enemy/Sprite"); ``` ### 节点验证 #### IsValidNode() 检查节点是否有效且在场景树中。 ```csharp public static bool IsValidNode(this Node node); ``` #### IsInvalidNode() 检查节点是否无效或不在场景树中。 ```csharp public static bool IsInvalidNode(this Node node); ``` #### 使用示例 ```csharp Node someNode = GetNode("SomeNode"); if (IsValidNode(someNode)) { someNode.DoSomething(); } if (IsInvalidNode(someNode)) { // 节点无效,需要重新获取 } ``` ### 安全节点操作 #### AddChildX() 安全添加子节点,包含验证。 ```csharp public static void AddChildX(this Node parent, Node child, bool forceReadableName = false, InternalMode internalMode = 0); ``` #### QueueFreeX() 安全销毁节点,包含验证。 ```csharp public static void QueueFreeX(this Node node); ``` #### FreeX() 立即销毁节点,谨慎使用。 ```csharp public static void FreeX(this Node node); ``` #### 使用示例 ```csharp // 创建并添加子节点 var bullet = bulletScene.Instantiate(); AddChildX(bullet); // 安全销毁节点 bullet.QueueFreeX(); // 立即销毁(谨慎使用) tempNode.FreeX(); ``` ### 异步节点操作 #### WaitUntilReady() 等待节点准备就绪。 ```csharp public static async Task WaitUntilReady(this Node node); ``` #### WaitUntil() 等待条件满足。 ```csharp public static async Task WaitUntil(this Node node, Func condition); ``` #### WaitUntilTimeout() 等待指定时间或条件满足。 ```csharp public static async Task WaitUntilTimeout(this Node node, float timeoutSeconds); ``` #### 使用示例 ```csharp // 等待节点准备就绪 await this.WaitUntilReady(); // 等待条件满足 await this.WaitUntil(() => SomeCondition()); // 等待 2 秒 await this.WaitUntilTimeout(2.0f); ``` ### 场景树操作 #### GetParentX() 安全获取父节点。 ```csharp public static T GetParentX(this Node node) where T : class; ``` #### ForEachChild() 遍历所有子节点。 ```csharp public static void ForEachChild(this Node node, Action action) where T : Node; ``` #### 使用示例 ```csharp // 获取父节点 var parent = GetParentX(); // 遍历所有子节点 this.ForEachChild(child => { if (child is Sprite2D sprite) { ProcessSprite(sprite); } }); ``` ## 信号系统 ### SignalBuilder 信号构建器,提供流畅的信号连接 API。 #### 构造函数 ```csharp public SignalBuilder(Node node); ``` #### 连接方法 ```csharp public SignalBuilder Connect(Callable callable); public SignalBuilder Connect(Callable callable); public SignalBuilder Connect(Callable callable); public SignalBuilder Connect(Callable callable); public SignalBuilder Connect(Callable callable); ``` #### 配置方法 ```csharp public SignalBuilder WithFlags(ConnectFlags flags); public SignalBuilder CallImmediately(); ``` #### 生命周期方法 ```csharp public SignalBuilder UnRegisterWhenNodeExitTree(Node node); public SignalBuilder AddToUnregisterList(IUnRegisterList unregisterList); ``` #### 使用示例 ```csharp // 基础连接 this.CreateSignalBuilder(Button.SignalName.Pressed) .Connect(OnButtonPressed) .UnRegisterWhenNodeExitTree(this); // 带标志的连接 this.CreateSignalBuilder(Timer.SignalName.Timeout) .WithFlags(ConnectFlags.OneShot) .Connect(OnTimerTimeout); // 立即调用连接 this.CreateSignalBuilder(CustomSignal.SignalName.CustomEvent) .CallImmediately() .Connect(OnCustomEvent); // 多参数连接 this.CreateSignalBuilder() .AddSignal(SignalName.Parameter1, OnParameter1) .AddSignal(SignalName.Parameter2, OnParameter2) .AddSignal(SignalName.Parameter3, OnParameter3) .UnRegisterWhenNodeExitTree(this); ``` ### SignalExtension 信号扩展方法,简化信号创建。 #### CreateSignalBuilder() 创建信号构建器。 ```csharp public static SignalBuilder CreateSignalBuilder(this Node node, string signalName); ``` #### ConnectSignal() 直接连接信号。 ```csharp public static IUnRegister ConnectSignal(this Node node, string signalName, Callable callable); public static IUnRegister ConnectSignal(this Node node, string signalName, Callable callable); ``` #### 使用示例 ```csharp // 创建信号构建器连接 this.CreateSignalBuilder(Button.SignalName.Pressed) .Connect(OnButtonPressed); // 直接连接信号 this.ConnectSignal(Button.SignalName.Pressed, Callable.From(OnButtonPressed)); // 多参数信号连接 this.ConnectSignal(ComplexSignal.SignalName.DataChanged, Callable.From(OnDataChanged)); ``` ### 信号与框架事件桥接 #### SignalEventBridge 信号事件桥接器,将 Godot 信号转换为框架事件。 #### 使用示例 ```csharp [ContextAware] [Log] public partial class GameController : Node, IController { public override void _Ready() { // Godot 信号 -> 框架事件 this.CreateSignalBuilder(Button.SignalName.Pressed) .Connect(() => { Context.SendEvent(new ButtonClickEvent { ButtonId = "start" }); }) .UnRegisterWhenNodeExitTree(this); // 框架事件 -> Godot 信号 this.RegisterEvent(OnPlayerHealthChange) .UnRegisterWhenNodeExitTree(this); } private void OnPlayerHealthChange(PlayerHealthChangeEvent e) { // 更新 Godot UI var healthBar = GetNode("UI/HealthBar"); healthBar.Value = (float)e.NewHealth / e.MaxHealth * 100; // 发送 Godot 信号 EmitSignal(SignalName.HealthUpdated, e.NewHealth, e.MaxHealth); } [Signal] public delegate void HealthUpdatedEventHandler(int newHealth, int maxHealth); } ``` ## 节点池化 ### AbstractNodePoolSystem 节点池化系统基类,TNode 必须是 Node。 #### 抽象方法 ```csharp protected abstract TNode CreateItem(TKey key); protected abstract void OnSpawn(TNode item, TKey key); protected abstract void OnDespawn(TNode item); protected abstract bool CanDespawn(TNode item); ``` #### 公共方法 ```csharp public TNode Spawn(TKey key); public void Despawn(TNode item); public void DespawnAll(); public int GetActiveCount(TKey key); public int GetTotalCount(TKey key); ``` #### 使用示例 ```csharp public class BulletPoolSystem : AbstractNodePoolSystem { private readonly Dictionary _scenes = new(); public BulletPoolSystem() { _scenes["player"] = GD.Load("res://scenes/PlayerBullet.tscn"); _scenes["enemy"] = GD.Load("res://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; } } // 使用示例 var bulletPool = new BulletPoolSystem(); // 从池中获取子弹 var bullet = bulletPool.Spawn("player"); AddChild(bullet); // 回收子弹 bulletPool.Despawn(bullet); ``` ### IPoolableNode 可池化节点接口。 ```csharp public interface IPoolableNode { void Reset(); void SetActive(bool active); bool IsActive { get; } } ``` #### 使用示例 ```csharp public partial class Bullet : Area2D, IPoolableNode { [Export] public float Speed { get; set; } = 500.0f; [Export] public float Damage { get; set; } = 10.0f; private bool _isActive; public bool IsActive => _isActive; public void Reset() { Position = Vector2.Zero; Rotation = 0; Velocity = Vector2.Zero; _isActive = false; } public void SetActive(bool active) { _isActive = active; Visible = active; SetProcess(active); } public override void _Ready() { BodyEntered += OnBodyEntered; } private void OnBodyEntered(Node body) { if (body is Enemy enemy && _isActive) { enemy.TakeDamage(Damage); // 子弹命中敌人,回收到池中 var bulletPool = GetNode("/root/BulletPool"); bulletPool?.Despawn(this); } } public override void _Process(double delta) { if (!_isActive) return; Position += Transform.X * (float)(Speed * delta); } } ``` ## 资源管理 ### ResourceLoadUtility 资源加载工具类,简化和缓存 Godot 资源加载。 #### 构造函数 ```csharp public ResourceLoadUtility(); ``` #### 方法 ```csharp public T LoadResource(string path) where T : Resource; public async Task LoadResourceAsync(string path) where T : Resource; public void PreloadResource(string path) where T : Resource; public bool HasResource(string path) where T : Resource; ``` #### 使用示例 ```csharp var resourceLoader = new ResourceLoadUtility(); // 同步加载资源 var playerTexture = resourceLoader.LoadResource("res://textures/player.png"); var playerScene = resourceLoader.LoadResource("res://scenes/Player.tscn"); // 异步加载资源 var musicStream = await resourceLoader.LoadResourceAsync("res://audio/background.ogg"); // 预加载资源 resourceLoader.PreloadResource("res://textures/enemy.png"); resourceLoader.PreloadResource("res://scenes/enemy.tscn"); ``` ### AbstractResourceFactoryUtility 抽象资源工厂工具基类。 #### 抽象方法 ```csharp protected abstract void RegisterFactories(); protected abstract T CreateFactory(string path, Dictionary metadata = null) where T : class; ``` #### 使用示例 ```csharp public class GameResourceFactory : AbstractResourceFactoryUtility { protected override void RegisterFactories() { RegisterFactory("res://data/players/{id}.json"); RegisterFactory("res://data/weapons/{id}.json"); RegisterFactory("res://data/levels/{id}.json"); } public PlayerData CreatePlayer(string playerId) { return CreateFactory($"res://data/players/{playerId}.json"); } public WeaponConfig CreateWeapon(string weaponId) { var metadata = new Dictionary { ["weaponId"] = weaponId, ["loadTime"] = DateTime.Now }; return CreateFactory($"res://data/weapons/{weaponId}.json", metadata); } } ``` ## 日志系统 ### GodotLogger Godot 特定的日志实现。 #### 构造函数 ```csharp public GodotLogger(string categoryName); public GodotLogger(string categoryName, LogLevel minLevel); ``` #### 方法 ```csharp public void Log(LogLevel level, T message, params object[] args); public void Debug(T message, params object[] args); public void Info(T message, params object[] args); public void Warning(T message, params object[] args); public void Error(T message, params object[] args); public void Error(Exception exception, T message, params object[] args); ``` #### 使用示例 ```csharp // 创建日志器 var logger = new GodotLogger("GameController"); // 不同级别的日志 logger.Debug("Player position: {0}", player.Position); logger.Info("Game started"); logger.Warning("Low health: {0}", player.Health); logger.Error("Failed to load resource: {0}", resourcePath); // 带异常的错误日志 logger.Error(exception, "An error occurred while processing player input"); ``` ### GodotLoggerFactory Godot 日志工厂。 #### 方法 ```csharp public ILogger CreateLogger(string categoryName); public ILogger CreateLogger(Type type); ``` #### 使用示例 ```csharp var factory = new GodotLoggerFactory(); // 创建日志器 var gameLogger = factory.CreateLogger("GameController"); var playerLogger = factory.CreateLogger(typeof(PlayerController)); // 在架构中使用 public class GameArchitecture : AbstractArchitecture { protected override void Init() { LoggerProperties = new LoggerProperties { LoggerFactoryProvider = new GodotLoggerFactoryProvider(), MinLevel = LogLevel.Info }; RegisterSystem(new GameController()); } } ``` ## 池化管理 ### AbstractObjectPool 通用对象池基类。 #### 构造函数 ```csharp public AbstractObjectPool( Func createFunc, Action actionOnGet = null, Action actionOnRelease = null, bool collectionCheck = false ); ``` #### 方法 ```csharp public T Get(); public void Release(T item); public void Clear(); public int CountInactive { get; } public int CountAll { get; } ``` #### 使用示例 ```csharp // 创建对象池 var explosionPool = new AbstractObjectPool( createFunc: () => new ExplosionEffect(), actionOnGet: effect => effect.Reset(), actionOnRelease: effect => Cleanup() ); // 使用对象池 var effect = explosionPool.Get(); effect.Play(effect.Position); // 回收对象 explosionPool.Release(effect); ``` --- ## 音频系统 ### AudioSystem 音频系统,管理音乐和音效播放。 #### 使用示例 ```csharp [ContextAware] [Log] public partial class AudioSystem : AbstractSystem { private AudioStreamPlayer _musicPlayer; private readonly Dictionary _soundCache = new(); protected override void OnInit() { InitializeAudioPlayers(); CacheSounds(); // 监听音频事件 this.RegisterEvent(OnPlaySound); this.RegisterEvent(OnPlayMusic); this.RegisterEvent(OnStopMusic); this.RegisterEvent(OnSetVolume); } private void InitializeAudioPlayers() { _musicPlayer = new AudioStreamPlayer(); AddChild(_musicPlayer); // 配置音乐播放器 _musicPlayer.Bus = "Music"; } private void CacheSounds() { var soundPaths = new[] { "res://audio/jump.wav", "res://audio/attack.wav", "res://audio/hurt.wav", "res://audio/victory.wav" }; foreach (var path in soundPaths) { var sound = GD.Load(path); var soundName = Path.GetFileNameWithoutExtension(path); _soundCache[soundName] = sound; } } private void OnPlaySound(PlaySoundEvent e) { if (_soundCache.TryGetValue(e.SoundName, out var sound)) { PlaySound(sound); } else { Logger.Warning($"Sound not found: {e.SoundName}"); } } private void PlayMusic(PlayMusicEvent e) { var music = GD.Load(e.MusicPath); _musicPlayer.Stream = music; _musicPlayer.Play(); Logger.Info($"Playing music: {e.MusicPath}"); } private void OnStopMusic(StopMusicEvent e) { _musicPlayer.Stop(); Logger.Info("Music stopped"); } private void OnSetVolume(SetVolumeEvent e) { AudioServer.SetBusVolume(e.BusName, e.Volume); Logger.Info($"Set volume for bus {e.BusName}: {e.Volume}"); } private void PlaySound(AudioStream sound) { var player = new AudioStreamPlayer(); player.Stream = sound; player.Bus = "SFX"; player.Play(); // 自动清理播放器 this.CreateSignalBuilder(player.SignalName.Finished) .WithFlags(ConnectFlags.OneShot) .Connect(() => player.QueueFree()) .UnRegisterWhenNodeExitTree(this); } } // 音频事件 public struct PlaySoundEvent { public string SoundName; } public struct PlayMusicEvent { public string MusicPath; } public struct StopMusicEvent { } public struct SetVolumeEvent { public string BusName; public float Volume; } ``` --- **文档版本**: 1.0.0 **更新日期**: 2026-01-12