diff --git a/GFramework.Godot/input/GodotInputModule.cs b/GFramework.Godot/input/AbstractGodotInputModule.cs
similarity index 74%
rename from GFramework.Godot/input/GodotInputModule.cs
rename to GFramework.Godot/input/AbstractGodotInputModule.cs
index b498c39..0946b0a 100644
--- a/GFramework.Godot/input/GodotInputModule.cs
+++ b/GFramework.Godot/input/AbstractGodotInputModule.cs
@@ -11,23 +11,31 @@ namespace GFramework.Godot.input;
/// Godot输入模块类,用于管理Godot游戏引擎中的输入系统
///
/// 架构类型,必须继承自Architecture且具有无参构造函数
-public sealed class GodotInputModule : AbstractGodotModule
+public abstract class AbstractGodotInputModule : AbstractGodotModule
where T : Architecture, new()
{
private GodotInputBridge? _node;
+
+ ///
+ /// 启用默认的输入转换器
+ ///
+ protected virtual bool EnableDefaultTranslator => false;
+
///
/// 架构锚点节点的唯一标识名称
/// 用于在Godot场景树中创建和查找架构锚点节点
///
private const string GodotInputBridgeName = $"__${GFrameworkConstants.FrameworkName}__GodotInputBridge__";
+
///
/// 获取模块对应的节点对象
///
/// 当节点尚未创建时抛出异常
- public override Node Node => _node
+ public override Node Node => _node
?? throw new InvalidOperationException("Node not created yet");
+
private InputSystem _inputSystem = null!;
-
+
///
/// 当模块被附加到架构时调用此方法
///
@@ -35,7 +43,7 @@ public sealed class GodotInputModule : AbstractGodotModule
public override void OnAttach(Architecture architecture)
{
// 创建Godot输入桥接节点并绑定输入系统
- _node = new GodotInputBridge { Name = GodotInputBridgeName};
+ _node = new GodotInputBridge { Name = GodotInputBridgeName };
_node.Bind(_inputSystem);
}
@@ -57,7 +65,18 @@ public sealed class GodotInputModule : AbstractGodotModule
{
// 从架构中获取输入系统实例
_inputSystem = architecture.GetSystem()!;
- // 注册输入转换器
- _inputSystem.RegisterTranslator(new GodotInputTranslator());
+ if (EnableDefaultTranslator)
+ {
+ // 注册输入转换器
+ _inputSystem.RegisterTranslator(new GodotInputTranslator(), true);
+ }
+
+ RegisterTranslator(_inputSystem);
}
-}
+
+ ///
+ /// 注册翻译器的抽象方法,由子类实现具体的注册逻辑
+ ///
+ /// 输入系统实例
+ protected abstract void RegisterTranslator(InputSystem inputSystem);
+}
\ No newline at end of file
diff --git a/GFramework.Godot/input/GodotInputBridge.cs b/GFramework.Godot/input/GodotInputBridge.cs
index 27f3ebf..cfb6b71 100644
--- a/GFramework.Godot/input/GodotInputBridge.cs
+++ b/GFramework.Godot/input/GodotInputBridge.cs
@@ -20,11 +20,22 @@ public partial class GodotInputBridge : Node
}
///
- /// 处理输入事件的回调方法
+ /// 捕获阶段:最早
///
- /// Godot输入事件
public override void _Input(InputEvent @event)
{
- _inputSystem.HandleRaw(@event);
+ _inputSystem.HandleRaw(
+ new GodotRawInput(@event, GodotInputPhase.Capture)
+ );
+ }
+
+ ///
+ /// 冒泡阶段:UI 未处理
+ ///
+ public override void _UnhandledInput(InputEvent @event)
+ {
+ _inputSystem.HandleRaw(
+ new GodotRawInput(@event, GodotInputPhase.Bubble)
+ );
}
}
diff --git a/GFramework.Godot/input/GodotInputPhase.cs b/GFramework.Godot/input/GodotInputPhase.cs
new file mode 100644
index 0000000..e250a8d
--- /dev/null
+++ b/GFramework.Godot/input/GodotInputPhase.cs
@@ -0,0 +1,19 @@
+namespace GFramework.Godot.input;
+
+///
+/// 输入处理阶段枚举,用于区分Godot引擎中不同的输入处理阶段
+///
+public enum GodotInputPhase
+{
+ ///
+ /// 捕获阶段,在_Input方法中处理输入事件
+ /// 这是输入事件的第一个处理阶段,事件会沿着节点树向下传递
+ ///
+ Capture, // _Input
+
+ ///
+ /// 冒泡阶段,在_UnhandledInput方法中处理输入事件
+ /// 这是输入事件的第二个处理阶段,未被处理的事件会向上冒泡传递
+ ///
+ Bubble // _UnhandledInput
+}
diff --git a/GFramework.Godot/input/GodotInputTranslator.cs b/GFramework.Godot/input/GodotInputTranslator.cs
index b01d1cd..9ac1ba9 100644
--- a/GFramework.Godot/input/GodotInputTranslator.cs
+++ b/GFramework.Godot/input/GodotInputTranslator.cs
@@ -18,12 +18,16 @@ public sealed class GodotInputTranslator : IInputTranslator
{
gameEvent = null!;
- // 检查输入是否为Godot的InputEvent类型
- if (rawInput is not InputEvent evt)
+ if (rawInput is not GodotRawInput raw)
+ return false;
+
+ var evt = raw.Event;
+
+ // 示例规则:只在 Bubble 阶段生成游戏输入
+ if (raw.Phase != GodotInputPhase.Bubble)
return false;
// Action
- // 处理动作输入事件(如键盘按键、手柄按钮等)
if (evt is InputEventAction action)
{
gameEvent = new InputEvents.KeyInputEvent(
@@ -35,7 +39,6 @@ public sealed class GodotInputTranslator : IInputTranslator
}
// Mouse button
- // 处理鼠标按钮输入事件
if (evt is InputEventMouseButton mb)
{
gameEvent = new InputEvents.PointerInputEvent(
@@ -48,7 +51,6 @@ public sealed class GodotInputTranslator : IInputTranslator
}
// Mouse motion
- // 处理鼠标移动输入事件
if (evt is InputEventMouseMotion mm)
{
gameEvent = new InputEvents.PointerInputEvent(
diff --git a/GFramework.Godot/input/GodotRawInput.cs b/GFramework.Godot/input/GodotRawInput.cs
new file mode 100644
index 0000000..1888c7f
--- /dev/null
+++ b/GFramework.Godot/input/GodotRawInput.cs
@@ -0,0 +1,21 @@
+using Godot;
+
+namespace GFramework.Godot.input;
+
+///
+/// 表示Godot原始输入数据的只读结构体
+///
+/// 输入事件对象
+/// 输入阶段
+public readonly struct GodotRawInput(InputEvent evt, GodotInputPhase phase)
+{
+ ///
+ /// 获取输入事件对象
+ ///
+ public readonly InputEvent Event = evt;
+
+ ///
+ /// 获取输入阶段
+ ///
+ public readonly GodotInputPhase Phase = phase;
+}