mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
```
refactor(input): 重构Godot输入模块为抽象基类并优化输入处理流程 将 `GodotInputModule` 重命名为 `AbstractGodotInputModule` 并改为抽象类, 以便支持更灵活的输入翻译器注册机制。引入 `GodotInputPhase` 枚举和 `GodotRawInput` 结构体以区分输入处理的不同阶段(捕获与冒泡)。 同时修改 `GodotInputTranslator` 仅在Bubble阶段生成游戏事件,提升输入处理精度。 ```
This commit is contained in:
parent
4bd9853ec1
commit
028ece27db
@ -11,23 +11,31 @@ namespace GFramework.Godot.input;
|
||||
/// Godot输入模块类,用于管理Godot游戏引擎中的输入系统
|
||||
/// </summary>
|
||||
/// <typeparam name="T">架构类型,必须继承自Architecture且具有无参构造函数</typeparam>
|
||||
public sealed class GodotInputModule<T> : AbstractGodotModule<T>
|
||||
public abstract class AbstractGodotInputModule<T> : AbstractGodotModule<T>
|
||||
where T : Architecture<T>, new()
|
||||
{
|
||||
private GodotInputBridge? _node;
|
||||
|
||||
/// <summary>
|
||||
/// 启用默认的输入转换器
|
||||
/// </summary>
|
||||
protected virtual bool EnableDefaultTranslator => false;
|
||||
|
||||
/// <summary>
|
||||
/// 架构锚点节点的唯一标识名称
|
||||
/// 用于在Godot场景树中创建和查找架构锚点节点
|
||||
/// </summary>
|
||||
private const string GodotInputBridgeName = $"__${GFrameworkConstants.FrameworkName}__GodotInputBridge__";
|
||||
|
||||
/// <summary>
|
||||
/// 获取模块对应的节点对象
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">当节点尚未创建时抛出异常</exception>
|
||||
public override Node Node => _node
|
||||
public override Node Node => _node
|
||||
?? throw new InvalidOperationException("Node not created yet");
|
||||
|
||||
private InputSystem _inputSystem = null!;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当模块被附加到架构时调用此方法
|
||||
/// </summary>
|
||||
@ -35,7 +43,7 @@ public sealed class GodotInputModule<T> : AbstractGodotModule<T>
|
||||
public override void OnAttach(Architecture<T> architecture)
|
||||
{
|
||||
// 创建Godot输入桥接节点并绑定输入系统
|
||||
_node = new GodotInputBridge { Name = GodotInputBridgeName};
|
||||
_node = new GodotInputBridge { Name = GodotInputBridgeName };
|
||||
_node.Bind(_inputSystem);
|
||||
}
|
||||
|
||||
@ -57,7 +65,18 @@ public sealed class GodotInputModule<T> : AbstractGodotModule<T>
|
||||
{
|
||||
// 从架构中获取输入系统实例
|
||||
_inputSystem = architecture.GetSystem<InputSystem>()!;
|
||||
// 注册输入转换器
|
||||
_inputSystem.RegisterTranslator(new GodotInputTranslator());
|
||||
if (EnableDefaultTranslator)
|
||||
{
|
||||
// 注册输入转换器
|
||||
_inputSystem.RegisterTranslator(new GodotInputTranslator(), true);
|
||||
}
|
||||
|
||||
RegisterTranslator(_inputSystem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册翻译器的抽象方法,由子类实现具体的注册逻辑
|
||||
/// </summary>
|
||||
/// <param name="inputSystem">输入系统实例</param>
|
||||
protected abstract void RegisterTranslator(InputSystem inputSystem);
|
||||
}
|
||||
@ -20,11 +20,22 @@ public partial class GodotInputBridge : Node
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理输入事件的回调方法
|
||||
/// 捕获阶段:最早
|
||||
/// </summary>
|
||||
/// <param name="event">Godot输入事件</param>
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
_inputSystem.HandleRaw(@event);
|
||||
_inputSystem.HandleRaw(
|
||||
new GodotRawInput(@event, GodotInputPhase.Capture)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 冒泡阶段:UI 未处理
|
||||
/// </summary>
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
_inputSystem.HandleRaw(
|
||||
new GodotRawInput(@event, GodotInputPhase.Bubble)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
19
GFramework.Godot/input/GodotInputPhase.cs
Normal file
19
GFramework.Godot/input/GodotInputPhase.cs
Normal file
@ -0,0 +1,19 @@
|
||||
namespace GFramework.Godot.input;
|
||||
|
||||
/// <summary>
|
||||
/// 输入处理阶段枚举,用于区分Godot引擎中不同的输入处理阶段
|
||||
/// </summary>
|
||||
public enum GodotInputPhase
|
||||
{
|
||||
/// <summary>
|
||||
/// 捕获阶段,在_Input方法中处理输入事件
|
||||
/// 这是输入事件的第一个处理阶段,事件会沿着节点树向下传递
|
||||
/// </summary>
|
||||
Capture, // _Input
|
||||
|
||||
/// <summary>
|
||||
/// 冒泡阶段,在_UnhandledInput方法中处理输入事件
|
||||
/// 这是输入事件的第二个处理阶段,未被处理的事件会向上冒泡传递
|
||||
/// </summary>
|
||||
Bubble // _UnhandledInput
|
||||
}
|
||||
@ -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<Vector2>(
|
||||
@ -48,7 +51,6 @@ public sealed class GodotInputTranslator : IInputTranslator
|
||||
}
|
||||
|
||||
// Mouse motion
|
||||
// 处理鼠标移动输入事件
|
||||
if (evt is InputEventMouseMotion mm)
|
||||
{
|
||||
gameEvent = new InputEvents.PointerInputEvent<Vector2>(
|
||||
|
||||
21
GFramework.Godot/input/GodotRawInput.cs
Normal file
21
GFramework.Godot/input/GodotRawInput.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using Godot;
|
||||
|
||||
namespace GFramework.Godot.input;
|
||||
|
||||
/// <summary>
|
||||
/// 表示Godot原始输入数据的只读结构体
|
||||
/// </summary>
|
||||
/// <param name="evt">输入事件对象</param>
|
||||
/// <param name="phase">输入阶段</param>
|
||||
public readonly struct GodotRawInput(InputEvent evt, GodotInputPhase phase)
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取输入事件对象
|
||||
/// </summary>
|
||||
public readonly InputEvent Event = evt;
|
||||
|
||||
/// <summary>
|
||||
/// 获取输入阶段
|
||||
/// </summary>
|
||||
public readonly GodotInputPhase Phase = phase;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user