From 339498e629f9331c5413924bb5a16176d11ae756 Mon Sep 17 00:00:00 2001
From: GwWuYou <95328647+GeWuYou@users.noreply.github.com>
Date: Sun, 21 Dec 2025 16:13:16 +0800
Subject: [PATCH] =?UTF-8?q?feat(GFramework.Godot):=20=E5=BC=95=E5=85=A5=20?=
=?UTF-8?q?Godot=20=E8=BE=93=E5=85=A5=E6=A8=A1=E5=9D=97=E4=B8=8E=E6=9E=B6?=
=?UTF-8?q?=E6=9E=84=E9=94=9A=E7=82=B9=E9=87=8D=E6=9E=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
新增 GodotInputModule 和相关输入事件类型,实现 Godot 输入系统与游戏框架的桥接。
重构架构锚点类名及其引用,统一使用 GFrameworkConstants 中定义的框架名称常量。
添加 AbstractGodotModule 基类以规范模块行为,并完善输入事件记录类定义。
---
.../constants/GFrameworkConstants.cs | 12 +++
GFramework.Game/input/InputEvents.cs | 33 ++++++++
.../architecture/AbstractArchitecture.cs | 11 +--
.../architecture/AbstractGodotModule.cs | 58 ++++++++++++++
...ureAnchorNode.cs => ArchitectureAnchor.cs} | 4 +-
.../AbstractResourceFactorySystem.cs | 0
.../{system => assets}/IResourceLoadSystem.cs | 0
.../{system => assets}/ResourceLoadSystem.cs | 0
GFramework.Godot/input/GodotInputBridge.cs | 79 +++++++++++++++++++
GFramework.Godot/input/GodotInputModule.cs | 61 ++++++++++++++
GFramework.sln.DotSettings.user | 2 +
11 files changed, 253 insertions(+), 7 deletions(-)
create mode 100644 GFramework.Core/constants/GFrameworkConstants.cs
create mode 100644 GFramework.Game/input/InputEvents.cs
create mode 100644 GFramework.Godot/architecture/AbstractGodotModule.cs
rename GFramework.Godot/architecture/{ArchitectureAnchorNode.cs => ArchitectureAnchor.cs} (84%)
rename GFramework.Godot/{system => assets}/AbstractResourceFactorySystem.cs (100%)
rename GFramework.Godot/{system => assets}/IResourceLoadSystem.cs (100%)
rename GFramework.Godot/{system => assets}/ResourceLoadSystem.cs (100%)
create mode 100644 GFramework.Godot/input/GodotInputBridge.cs
create mode 100644 GFramework.Godot/input/GodotInputModule.cs
create mode 100644 GFramework.sln.DotSettings.user
diff --git a/GFramework.Core/constants/GFrameworkConstants.cs b/GFramework.Core/constants/GFrameworkConstants.cs
new file mode 100644
index 0000000..ef0e309
--- /dev/null
+++ b/GFramework.Core/constants/GFrameworkConstants.cs
@@ -0,0 +1,12 @@
+namespace GFramework.Core.constants;
+
+///
+/// GFramework框架常量定义类
+///
+public static class GFrameworkConstants
+{
+ ///
+ /// 框架名称常量
+ ///
+ public const string FrameworkName = "GFramework";
+}
diff --git a/GFramework.Game/input/InputEvents.cs b/GFramework.Game/input/InputEvents.cs
new file mode 100644
index 0000000..3e672e2
--- /dev/null
+++ b/GFramework.Game/input/InputEvents.cs
@@ -0,0 +1,33 @@
+using System.Numerics;
+
+namespace GFramework.Game.input;
+
+public static class InputEvents
+{
+ ///
+ /// 按键输入事件
+ ///
+ /// 按键操作名称
+ /// 按键是否被按下,true表示按下,false表示释放
+ /// 是否为回显事件,用于处理按键重复触发
+ public sealed record KeyInputEvent(
+ string Action,
+ bool Pressed,
+ bool Echo
+ ) : IGameInputEvent;
+
+ ///
+ /// 指针/鼠标输入事件
+ ///
+ /// 二维向量类型
+ /// 指针当前位置坐标
+ /// 指针位置变化量
+ /// 鼠标按键编号,0表示左键,1表示右键,2表示中键
+ /// 按键是否被按下,true表示按下,false表示释放
+ public sealed record PointerInputEvent(
+ TVector2 Position,
+ TVector2 Delta,
+ int Button,
+ bool Pressed
+ ) : IGameInputEvent where TVector2 : struct;
+}
\ No newline at end of file
diff --git a/GFramework.Godot/architecture/AbstractArchitecture.cs b/GFramework.Godot/architecture/AbstractArchitecture.cs
index bd88d30..4d0476e 100644
--- a/GFramework.Godot/architecture/AbstractArchitecture.cs
+++ b/GFramework.Godot/architecture/AbstractArchitecture.cs
@@ -1,4 +1,5 @@
using GFramework.Core.architecture;
+using GFramework.Core.constants;
using GFramework.Godot.extensions;
using Godot;
@@ -16,7 +17,7 @@ public abstract class AbstractArchitecture : Architecture where T : Archit
/// 架构锚点节点的唯一标识名称
/// 用于在Godot场景树中创建和查找架构锚点节点
///
- private const string ArchitectureName = "__GFramework__Architecture__Anchor";
+ private const string ArchitectureAnchorName = $"__${GFrameworkConstants.FrameworkName}__ArchitectureAnchor__";
///
/// 存储所有已安装的Godot架构扩展组件列表
@@ -28,7 +29,7 @@ public abstract class AbstractArchitecture : Architecture where T : Archit
/// 架构锚点节点引用
/// 用于将架构绑定到Godot生命周期并作为扩展节点的父节点
///
- private ArchitectureAnchorNode? _anchor;
+ private ArchitectureAnchor? _anchor;
///
/// 获取架构根节点。如果尚未初始化或已被销毁,则抛出异常。
@@ -69,12 +70,12 @@ public abstract class AbstractArchitecture : Architecture where T : Archit
return;
// 防止重复挂载(热重载 / 多次 Init)
- if (tree.Root.GetNodeOrNull(ArchitectureName) != null)
+ if (tree.Root.GetNodeOrNull(ArchitectureAnchorName) != null)
return;
- _anchor = new ArchitectureAnchorNode
+ _anchor = new ArchitectureAnchor
{
- Name = ArchitectureName
+ Name = ArchitectureAnchorName
};
_anchor.Bind(Destroy);
diff --git a/GFramework.Godot/architecture/AbstractGodotModule.cs b/GFramework.Godot/architecture/AbstractGodotModule.cs
new file mode 100644
index 0000000..e89975b
--- /dev/null
+++ b/GFramework.Godot/architecture/AbstractGodotModule.cs
@@ -0,0 +1,58 @@
+using GFramework.Core.architecture;
+using Godot;
+
+namespace GFramework.Godot.architecture;
+
+///
+/// 抽象的Godot模块基类,用于定义Godot框架中的模块行为
+///
+/// 架构类型,必须继承自Architecture并且有无参构造函数
+public abstract class AbstractGodotModule: IGodotModule where T : Architecture, new()
+{
+ ///
+ /// 当架构阶段发生变化时调用此方法
+ ///
+ /// 当前的架构阶段
+ /// 架构实例
+ public virtual void OnPhase(ArchitecturePhase phase, IArchitecture arch)
+ {
+
+ }
+
+ ///
+ /// 当架构阶段发生变化时调用此方法
+ ///
+ /// 当前的架构阶段
+ public virtual void OnArchitecturePhase(ArchitecturePhase phase)
+ {
+
+ }
+
+ ///
+ /// 安装模块到指定架构中
+ ///
+ /// 要安装到的架构实例
+ public abstract void Install(IArchitecture architecture);
+
+ ///
+ /// 获取模块关联的Godot节点
+ ///
+ public abstract Node Node { get; }
+
+ ///
+ /// 当模块被附加到架构时调用此方法
+ ///
+ /// 被附加到的架构实例
+ public virtual void OnAttach(Architecture architecture)
+ {
+
+ }
+
+ ///
+ /// 当模块从架构中分离时调用此方法
+ ///
+ public virtual void OnDetach()
+ {
+
+ }
+}
diff --git a/GFramework.Godot/architecture/ArchitectureAnchorNode.cs b/GFramework.Godot/architecture/ArchitectureAnchor.cs
similarity index 84%
rename from GFramework.Godot/architecture/ArchitectureAnchorNode.cs
rename to GFramework.Godot/architecture/ArchitectureAnchor.cs
index ca1c0f4..4f41564 100644
--- a/GFramework.Godot/architecture/ArchitectureAnchorNode.cs
+++ b/GFramework.Godot/architecture/ArchitectureAnchor.cs
@@ -6,7 +6,7 @@ namespace GFramework.Godot.architecture;
/// 架构锚点节点类,用于在Godot场景树中作为架构组件的根节点
/// 该类提供了退出时的回调绑定功能,可以在节点从场景树中移除时执行清理操作
///
-public partial class ArchitectureAnchorNode : Node
+public partial class ArchitectureAnchor : Node
{
private Action? _onExit;
///
@@ -18,7 +18,7 @@ public partial class ArchitectureAnchorNode : Node
if (_onExit != null)
{
GD.PushWarning(
- $"{nameof(ArchitectureAnchorNode)} already bound. Rebinding will override previous callback.");
+ $"{nameof(ArchitectureAnchor)} already bound. Rebinding will override previous callback.");
}
_onExit = onExit;
}
diff --git a/GFramework.Godot/system/AbstractResourceFactorySystem.cs b/GFramework.Godot/assets/AbstractResourceFactorySystem.cs
similarity index 100%
rename from GFramework.Godot/system/AbstractResourceFactorySystem.cs
rename to GFramework.Godot/assets/AbstractResourceFactorySystem.cs
diff --git a/GFramework.Godot/system/IResourceLoadSystem.cs b/GFramework.Godot/assets/IResourceLoadSystem.cs
similarity index 100%
rename from GFramework.Godot/system/IResourceLoadSystem.cs
rename to GFramework.Godot/assets/IResourceLoadSystem.cs
diff --git a/GFramework.Godot/system/ResourceLoadSystem.cs b/GFramework.Godot/assets/ResourceLoadSystem.cs
similarity index 100%
rename from GFramework.Godot/system/ResourceLoadSystem.cs
rename to GFramework.Godot/assets/ResourceLoadSystem.cs
diff --git a/GFramework.Godot/input/GodotInputBridge.cs b/GFramework.Godot/input/GodotInputBridge.cs
new file mode 100644
index 0000000..7c89986
--- /dev/null
+++ b/GFramework.Godot/input/GodotInputBridge.cs
@@ -0,0 +1,79 @@
+using GFramework.Game.input;
+using Godot;
+
+namespace GFramework.Godot.input;
+
+///
+/// Godot输入桥接类,用于将Godot的输入事件转换为游戏框架的输入事件
+///
+public partial class GodotInputBridge : Node
+{
+ private InputSystem _inputSystem = null!;
+
+ ///
+ /// 绑定输入系统
+ ///
+ /// 要绑定的输入系统实例
+ public void Bind(InputSystem inputSystem)
+ {
+ _inputSystem = inputSystem;
+ }
+
+ ///
+ /// 处理输入事件的回调方法
+ ///
+ /// Godot输入事件
+ public override void _Input(InputEvent @event)
+ {
+ var gameEvent = Translate(@event);
+ if (gameEvent == null)
+ {
+ return;
+ }
+
+ _inputSystem.Handle(gameEvent);
+ GetViewport().SetInputAsHandled();
+ }
+
+ ///
+ /// 将Godot输入事件翻译为游戏框架输入事件
+ ///
+ /// Godot输入事件
+ /// 翻译后的游戏输入事件,如果无法翻译则返回null
+ private static IGameInputEvent? Translate(InputEvent evt)
+ {
+ // 处理动作输入事件
+ if (evt is InputEventAction action)
+ {
+ return new InputEvents.KeyInputEvent(
+ action.Action,
+ action.Pressed,
+ false
+ );
+ }
+
+ // 鼠标按钮
+ if (evt is InputEventMouseButton mb)
+ {
+ return new InputEvents.PointerInputEvent(
+ mb.Position,
+ Vector2.Zero,
+ (int)mb.ButtonIndex,
+ mb.Pressed
+ );
+ }
+
+ // 鼠标移动
+ if (evt is InputEventMouseMotion mm)
+ {
+ return new InputEvents.PointerInputEvent(
+ mm.Position,
+ mm.Relative,
+ 0,
+ false
+ );
+ }
+
+ return null;
+ }
+}
diff --git a/GFramework.Godot/input/GodotInputModule.cs b/GFramework.Godot/input/GodotInputModule.cs
new file mode 100644
index 0000000..9b020e3
--- /dev/null
+++ b/GFramework.Godot/input/GodotInputModule.cs
@@ -0,0 +1,61 @@
+using GFramework.Core.architecture;
+using GFramework.Core.constants;
+using GFramework.Game.input;
+using GFramework.Godot.architecture;
+using GFramework.Godot.extensions;
+using Godot;
+
+namespace GFramework.Godot.input;
+
+///
+/// Godot输入模块类,用于管理Godot游戏引擎中的输入系统
+///
+/// 架构类型,必须继承自Architecture且具有无参构造函数
+public sealed class GodotInputModule : AbstractGodotModule
+ where T : Architecture, new()
+{
+ private GodotInputBridge? _node;
+ ///
+ /// 架构锚点节点的唯一标识名称
+ /// 用于在Godot场景树中创建和查找架构锚点节点
+ ///
+ private const string GodotInputBridgeName = $"__${GFrameworkConstants.FrameworkName}__GodotInputBridge__";
+ ///
+ /// 获取模块对应的节点对象
+ ///
+ /// 当节点尚未创建时抛出异常
+ public override Node Node => _node
+ ?? throw new InvalidOperationException("Node not created yet");
+ private InputSystem _inputSystem = null!;
+
+ ///
+ /// 当模块被附加到架构时调用此方法
+ ///
+ /// 要附加到的架构实例
+ public override void OnAttach(Architecture architecture)
+ {
+ // 创建Godot输入桥接节点并绑定输入系统
+ _node = new GodotInputBridge { Name = GodotInputBridgeName};
+ _node.Bind(_inputSystem);
+ }
+
+ ///
+ /// 当模块从架构中分离时调用此方法
+ ///
+ public override void OnDetach()
+ {
+ // 释放节点资源并清理引用
+ Node.QueueFreeX();
+ _node = null;
+ }
+
+ ///
+ /// 安装模块时调用此方法,用于获取所需的系统组件
+ ///
+ /// 当前架构实例
+ public override void Install(IArchitecture architecture)
+ {
+ // 从架构中获取输入系统实例
+ _inputSystem = architecture.GetSystem()!;
+ }
+}
diff --git a/GFramework.sln.DotSettings.user b/GFramework.sln.DotSettings.user
new file mode 100644
index 0000000..c18f938
--- /dev/null
+++ b/GFramework.sln.DotSettings.user
@@ -0,0 +1,2 @@
+
+ ForceIncluded
\ No newline at end of file