Godot - Input.is_action_just_pressed() 运行两次
Godot - Input.is_action_just_pressed() runs twice
所以我设置了 Q 和 E 来控制固定在 8 个方向上的相机。问题是当我调用 Input.is_action_just_pressed() 时它设置为真两次,所以它的内容两次。
这是它对计数器的作用:
0 0 0 0 1 1 2 2 2 2
我该如何解决这个问题?
if Input.is_action_just_pressed("camera_right", true):
if cardinal_count < cardinal_index.size() - 1:
cardinal_count += 1
else:
cardinal_count = 0
emit_signal("cardinal_count_changed", cardinal_count)
所以,显然有一个内置的回声检测方法:
is_echo()
我关闭这个。
在 _process
或 _physics_process
如果代码在 _process
或 _physics_process
.
中为 运行,则您的代码应该可以正常工作 - 无需报告两次
这是因为如果在当前帧中按下操作,is_action_just_pressed
将return。默认情况下,这意味着图形框架,但该方法实际上会检测它是在物理框架还是图形框架中调用,如您在 its source code 中所见。根据设计,每个图形帧只调用一次 _process
,每个物理帧调用一次 _physics_process
。
在 _input
但是,如果您是 运行 _input
中的代码,请记住您会为每个输入事件调用 _input
。并且单个框架中可以有多个。因此,可以多次调用 _input
,其中 is_action_just_pressed
。那是因为它们在同一个框架(图形框架,这是默认的)。
现在,让我们看看建议的解决方案(来自 ):
if event is InputEventKey:
if Input.is_action_just_pressed("camera_right", true) and not event.is_echo():
# whatever
pass
检测当前图形帧中是否按下了"camera_right"
动作。但它可能是一个与当前正在处理的事件不同的输入事件 (event
)。
因此,你可以骗过这段代码。同时按下配置为 "camera_right"
的键和其他东西(或足够快以在同一帧中),执行将进入那里两次。这是我们正在努力避免的。
要正确避免它,您需要检查当前的 event
是否是您感兴趣的操作。您可以使用 event.is_action("camera_right")
执行此操作。现在,你有一个选择。你可以这样做:
if event.is_action("camera_right") and event.is_pressed() and not event.is_echo():
# whatever
pass
这就是我的建议。它检查它是正确的动作,它是一个按下(而不是释放)事件,它不是一个回声(形式 keyboard repetition)。
或者您可以这样做:
if event.is_action("camera_right") and Input.is_action_just_pressed("camera_right", true) and not event.is_echo():
# whatever
pass
我不建议这样做是因为:首先,它更长;其次,is_action_just_pressed
并不意味着要在 _input
中使用。由于 is_action_just_pressed
与框架的概念相关。 is_action_just_pressed
的设计旨在与 _process
或 _physics_process
一起使用,而不是 _input
.
我遇到了同样的问题,在我的情况下,这是因为我的场景(包含 Input.is_action_just_pressed 检查的场景)被放置在场景树中,并且也是自动加载的,这意味着从两个位置都获取了输入并执行了两次。
我把它作为自动加载取出,Input.is_action_just_pressed 现在每个输入触发一次。
所以我设置了 Q 和 E 来控制固定在 8 个方向上的相机。问题是当我调用 Input.is_action_just_pressed() 时它设置为真两次,所以它的内容两次。
这是它对计数器的作用:
0 0 0 0 1 1 2 2 2 2
我该如何解决这个问题?
if Input.is_action_just_pressed("camera_right", true):
if cardinal_count < cardinal_index.size() - 1:
cardinal_count += 1
else:
cardinal_count = 0
emit_signal("cardinal_count_changed", cardinal_count)
所以,显然有一个内置的回声检测方法: is_echo()
我关闭这个。
在 _process
或 _physics_process
如果代码在 _process
或 _physics_process
.
这是因为如果在当前帧中按下操作,is_action_just_pressed
将return。默认情况下,这意味着图形框架,但该方法实际上会检测它是在物理框架还是图形框架中调用,如您在 its source code 中所见。根据设计,每个图形帧只调用一次 _process
,每个物理帧调用一次 _physics_process
。
在 _input
但是,如果您是 运行 _input
中的代码,请记住您会为每个输入事件调用 _input
。并且单个框架中可以有多个。因此,可以多次调用 _input
,其中 is_action_just_pressed
。那是因为它们在同一个框架(图形框架,这是默认的)。
现在,让我们看看建议的解决方案(来自
if event is InputEventKey:
if Input.is_action_just_pressed("camera_right", true) and not event.is_echo():
# whatever
pass
检测当前图形帧中是否按下了"camera_right"
动作。但它可能是一个与当前正在处理的事件不同的输入事件 (event
)。
因此,你可以骗过这段代码。同时按下配置为 "camera_right"
的键和其他东西(或足够快以在同一帧中),执行将进入那里两次。这是我们正在努力避免的。
要正确避免它,您需要检查当前的 event
是否是您感兴趣的操作。您可以使用 event.is_action("camera_right")
执行此操作。现在,你有一个选择。你可以这样做:
if event.is_action("camera_right") and event.is_pressed() and not event.is_echo():
# whatever
pass
这就是我的建议。它检查它是正确的动作,它是一个按下(而不是释放)事件,它不是一个回声(形式 keyboard repetition)。
或者您可以这样做:
if event.is_action("camera_right") and Input.is_action_just_pressed("camera_right", true) and not event.is_echo():
# whatever
pass
我不建议这样做是因为:首先,它更长;其次,is_action_just_pressed
并不意味着要在 _input
中使用。由于 is_action_just_pressed
与框架的概念相关。 is_action_just_pressed
的设计旨在与 _process
或 _physics_process
一起使用,而不是 _input
.
我遇到了同样的问题,在我的情况下,这是因为我的场景(包含 Input.is_action_just_pressed 检查的场景)被放置在场景树中,并且也是自动加载的,这意味着从两个位置都获取了输入并执行了两次。
我把它作为自动加载取出,Input.is_action_just_pressed 现在每个输入触发一次。