Godot输入系统概述

Godot的输入系统存在一个消耗的概念
所有的输入事件(InputEvent)都可以被某个节点消耗不再传播

Godot节点会处理下面的Input方法回调
(这里的是C#的函数签名)

public override void _Input(InputEvent @event);
public override void _GuiInput(InputEvent @event);
public override void _ShortcutInput(InputEvent @event);
public override void _UnhandledKeyInput(InputEvent @event);
public override void _UnhandledInput(InputEvent @event);

处理顺序也是按上面的顺序所示

对于节点来说,输入的处理顺序是从下到上的
比如这样

root (5)
├── Control1 (4)
|   ├── SubControl (3)
├── Control2 (2)
└── Control3 (1)

处理顺序如括号标注所示

需要注意的是,对于每个节点,并不是一次将5个Input方法按顺序处理一遍
也就是输入系统并不是按下面的顺序处理

Control3._Input(e);
Control3._GuiInput(e);
Control3._ShortcutInput(e);
Control3._UnhandledKeyInput(e);
Control3._UnhandledInput(e);

Control2._Input(e);
Control2._GuiInput(e);
Control2._ShortcutInput(e);
Control2._UnhandledKeyInput(e);
Control2._UnhandledInput(e);
// ...

而是按下面的顺序

Control3._Input(e);
Control2._Input(e);
SubControl._Input(e);
Control1._Input(e);
root._Input(e);

Control3._GuiInput(e);
Control2._GuiInput(e);
SubControl._GuiInput(e);
Control1._GuiInput(e);
root._GuiInput(e);
// ...

相当于是有5个Pass

Input方法是第一道Pass
Godot文档中建议是做输入的过滤,不把大量的逻辑写这里

GuiInput是Control专属的Input方法
这个方法会根据控件焦点再筛选一次

ShortcutInput是处理快捷键的方法

UnhandledKeyInput和UnhandledInput都算是最后的方法
看具体逻辑
一般建议优先级不高的输入写这里

除了GuiInput方法,其他输入方法中都可以通过GetViewport().SetInputAsHandled()消耗输入
GuiInput方法中建议使用AcceptEvent()来消耗
被消耗的输入事件就不会在传播给后面的节点