mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-24 12:33:30 +08:00
```
refactor(input): 重构Godot输入模块为抽象基类并优化输入处理流程 将 `GodotInputModule` 重命名为 `AbstractGodotInputModule` 并改为抽象类, 以便支持更灵活的输入翻译器注册机制。引入 `GodotInputPhase` 枚举和 `GodotRawInput` 结构体以区分输入处理的不同阶段(捕获与冒泡)。 同时修改 `GodotInputTranslator` 仅在Bubble阶段生成游戏事件,提升输入处理精度。 ```
This commit is contained in:
parent
4bd9853ec1
commit
dfe063fc88
@ -11,23 +11,31 @@ namespace GFramework.Godot.input;
|
|||||||
/// Godot输入模块类,用于管理Godot游戏引擎中的输入系统
|
/// Godot输入模块类,用于管理Godot游戏引擎中的输入系统
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">架构类型,必须继承自Architecture且具有无参构造函数</typeparam>
|
/// <typeparam name="T">架构类型,必须继承自Architecture且具有无参构造函数</typeparam>
|
||||||
public sealed class GodotInputModule<T> : AbstractGodotModule<T>
|
public abstract class AbstractGodotInputModule<T> : AbstractGodotModule<T>
|
||||||
where T : Architecture<T>, new()
|
where T : Architecture<T>, new()
|
||||||
{
|
{
|
||||||
private GodotInputBridge? _node;
|
private GodotInputBridge? _node;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启用默认的输入转换器
|
||||||
|
/// </summary>
|
||||||
|
protected virtual bool EnableDefaultTranslator => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 架构锚点节点的唯一标识名称
|
/// 架构锚点节点的唯一标识名称
|
||||||
/// 用于在Godot场景树中创建和查找架构锚点节点
|
/// 用于在Godot场景树中创建和查找架构锚点节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const string GodotInputBridgeName = $"__${GFrameworkConstants.FrameworkName}__GodotInputBridge__";
|
private const string GodotInputBridgeName = $"__${GFrameworkConstants.FrameworkName}__GodotInputBridge__";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取模块对应的节点对象
|
/// 获取模块对应的节点对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <exception cref="InvalidOperationException">当节点尚未创建时抛出异常</exception>
|
/// <exception cref="InvalidOperationException">当节点尚未创建时抛出异常</exception>
|
||||||
public override Node Node => _node
|
public override Node Node => _node
|
||||||
?? throw new InvalidOperationException("Node not created yet");
|
?? throw new InvalidOperationException("Node not created yet");
|
||||||
|
|
||||||
private InputSystem _inputSystem = null!;
|
private InputSystem _inputSystem = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当模块被附加到架构时调用此方法
|
/// 当模块被附加到架构时调用此方法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -35,7 +43,7 @@ public sealed class GodotInputModule<T> : AbstractGodotModule<T>
|
|||||||
public override void OnAttach(Architecture<T> architecture)
|
public override void OnAttach(Architecture<T> architecture)
|
||||||
{
|
{
|
||||||
// 创建Godot输入桥接节点并绑定输入系统
|
// 创建Godot输入桥接节点并绑定输入系统
|
||||||
_node = new GodotInputBridge { Name = GodotInputBridgeName};
|
_node = new GodotInputBridge { Name = GodotInputBridgeName };
|
||||||
_node.Bind(_inputSystem);
|
_node.Bind(_inputSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +65,18 @@ public sealed class GodotInputModule<T> : AbstractGodotModule<T>
|
|||||||
{
|
{
|
||||||
// 从架构中获取输入系统实例
|
// 从架构中获取输入系统实例
|
||||||
_inputSystem = architecture.GetSystem<InputSystem>()!;
|
_inputSystem = architecture.GetSystem<InputSystem>()!;
|
||||||
// 注册输入转换器
|
if (EnableDefaultTranslator)
|
||||||
_inputSystem.RegisterTranslator(new GodotInputTranslator());
|
{
|
||||||
|
// 注册输入转换器
|
||||||
|
_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>
|
||||||
/// 处理输入事件的回调方法
|
/// 捕获阶段:最早
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="event">Godot输入事件</param>
|
|
||||||
public override void _Input(InputEvent @event)
|
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!;
|
gameEvent = null!;
|
||||||
|
|
||||||
// 检查输入是否为Godot的InputEvent类型
|
if (rawInput is not GodotRawInput raw)
|
||||||
if (rawInput is not InputEvent evt)
|
return false;
|
||||||
|
|
||||||
|
var evt = raw.Event;
|
||||||
|
|
||||||
|
// 示例规则:只在 Bubble 阶段生成游戏输入
|
||||||
|
if (raw.Phase != GodotInputPhase.Bubble)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Action
|
// Action
|
||||||
// 处理动作输入事件(如键盘按键、手柄按钮等)
|
|
||||||
if (evt is InputEventAction action)
|
if (evt is InputEventAction action)
|
||||||
{
|
{
|
||||||
gameEvent = new InputEvents.KeyInputEvent(
|
gameEvent = new InputEvents.KeyInputEvent(
|
||||||
@ -35,7 +39,6 @@ public sealed class GodotInputTranslator : IInputTranslator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mouse button
|
// Mouse button
|
||||||
// 处理鼠标按钮输入事件
|
|
||||||
if (evt is InputEventMouseButton mb)
|
if (evt is InputEventMouseButton mb)
|
||||||
{
|
{
|
||||||
gameEvent = new InputEvents.PointerInputEvent<Vector2>(
|
gameEvent = new InputEvents.PointerInputEvent<Vector2>(
|
||||||
@ -48,7 +51,6 @@ public sealed class GodotInputTranslator : IInputTranslator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mouse motion
|
// Mouse motion
|
||||||
// 处理鼠标移动输入事件
|
|
||||||
if (evt is InputEventMouseMotion mm)
|
if (evt is InputEventMouseMotion mm)
|
||||||
{
|
{
|
||||||
gameEvent = new InputEvents.PointerInputEvent<Vector2>(
|
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