Control.accept_event
2026/4/14大约 4 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — Control.accept_event
Control.accept_event
定义
Control.accept_event 就是告诉 Godot:"这个输入事件我已经处理完了,不要再往下传了。"就像你在学校传纸条,你接到纸条后把它收起来不让后面的人看到。
打个比方:Godot 处理输入事件时,事件会从上层控件一层一层往下传递。如果你的控件处理了这个事件(比如一个按钮被点击了),就应该调用 accept_event() 把事件"吃掉",防止它继续传到后面的控件引发意外行为。
在实际游戏开发中,你经常需要在自定义控件中拦截某些输入事件,防止它们穿透到其他控件或游戏世界。比如拖拽 UI 窗口时,不应该同时触发游戏里的射击操作。
函数签名
C#
public void AcceptEvent()GDScript
func accept_event() -> void参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| 无 | — | — | 此方法没有参数 |
返回值
无返回值(void)。调用后当前输入事件被标记为"已处理"。
代码示例
基础用法:在输入处理中拦截事件
C#
using Godot;
public partial class CustomPanel : Control
{
public override void _GuiInput(InputEvent evt)
{
if (evt is InputEventMouseButton mouseBtn && mouseBtn.Pressed)
{
GD.Print("面板被点击了,事件已拦截");
AcceptEvent();
// 运行结果: 点击事件不会继续传递到后面的控件
}
}
}GDScript
extends Control
func _gui_input(evt):
if evt is InputEventMouseButton and evt.pressed:
print("面板被点击了,事件已拦截")
accept_event()
# 运行结果: 点击事件不会继续传递到后面的控件实际场景:防止拖拽 UI 时触发游戏操作
C#
using Godot;
public partial class DraggableWindow : Control
{
private bool _isDragging = false;
private Vector2 _dragOffset;
public override void _GuiInput(InputEvent evt)
{
if (evt is InputEventMouseButton mouseBtn)
{
if (mouseBtn.Pressed && mouseBtn.ButtonIndex == MouseButton.Left)
{
_isDragging = true;
_dragOffset = Position - mouseBtn.GlobalPosition;
AcceptEvent();
// 运行结果: 开始拖拽时拦截鼠标事件,防止穿透到 3D 场景
}
else if (!mouseBtn.Pressed && mouseBtn.ButtonIndex == MouseButton.Left)
{
_isDragging = false;
AcceptEvent();
// 运行结果: 松开鼠标时也拦截事件
}
}
if (evt is InputEventMouseMotion motion && _isDragging)
{
Position = motion.GlobalPosition + _dragOffset;
AcceptEvent();
// 运行结果: 拖拽过程中持续拦截鼠标移动事件
}
}
}GDScript
extends Control
var _is_dragging: bool = false
var _drag_offset: Vector2
func _gui_input(evt):
if evt is InputEventMouseButton:
if evt.pressed and evt.button_index == MOUSE_BUTTON_LEFT:
_is_dragging = true
_drag_offset = position - evt.global_position
accept_event()
# 运行结果: 开始拖拽时拦截鼠标事件
elif not evt.pressed and evt.button_index == MOUSE_BUTTON_LEFT:
_is_dragging = false
accept_event()
# 运行结果: 松开鼠标时也拦截事件
if evt is InputEventMouseMotion and _is_dragging:
position = evt.global_position + _drag_offset
accept_event()
# 运行结果: 拖拽过程中持续拦截鼠标移动事件进阶用法:自定义文本输入控件中拦截特定按键
C#
using Godot;
public partial class NumberInput : Control
{
private string _value = "";
private Label _displayLabel;
public override void _Ready()
{
_displayLabel = GetNode<Label>("DisplayLabel");
}
public override void _GuiInput(InputEvent evt)
{
if (evt is InputEventKey keyEvt && keyEvt.Pressed)
{
// 只允许数字键和退格键
var unicode = (char)keyEvt.Unicode;
if (char.IsDigit(unicode))
{
_value += unicode;
UpdateDisplay();
AcceptEvent();
// 运行结果: 数字键被处理并拦截
}
else if (keyEvt.Keycode == Key.Backspace)
{
if (_value.Length > 0)
{
_value = _value.Substring(0, _value.Length - 1);
UpdateDisplay();
}
AcceptEvent();
// 运行结果: 退格键被处理并拦截
}
else
{
// 非数字键也拦截,防止触发其他操作
AcceptEvent();
// 运行结果: 字母键等被静默忽略
}
}
}
private void UpdateDisplay()
{
_displayLabel.Text = _value.Length > 0 ? _value : "0";
// 运行结果: 显示当前输入的数字
}
}GDScript
extends Control
var _value: String = ""
@onready var _display_label: Label = $DisplayLabel
func _gui_input(evt):
if evt is InputEventKey and evt.pressed:
var unicode_char = char(evt.unicode)
if unicode_char.is_valid_int():
_value += unicode_char
update_display()
accept_event()
# 运行结果: 数字键被处理并拦截
elif evt.keycode == KEY_BACKSPACE:
if _value.length() > 0:
_value = _value.substr(0, _value.length() - 1)
update_display()
accept_event()
# 运行结果: 退格键被处理并拦截
else:
# 非数字键也拦截
accept_event()
# 运行结果: 字母键等被静默忽略
func update_display():
_display_label.text = _value if _value.length() > 0 else "0"
# 运行结果: 显示当前输入的数字注意事项
- 只能在
_GuiInput中调用:AcceptEvent()应该在_GuiInput回调中使用,不要在_Input或_UnhandledInput中使用。 - 阻止事件继续传播:调用后,事件不会再传递给下层控件,也不会触发
_UnhandledInput。 - 与
SetInputAsHandled()的区别:AcceptEvent()是 Control 的方法,在_GuiInput中使用;GetViewport().SetInputAsHandled()是全局方法,在_Input中使用。两者效果类似,但作用范围不同。 - 不是所有事件都需要拦截:只在确实需要阻止事件传播时才调用。如果只是想响应事件而不阻止传播,不需要调用
AcceptEvent()。
