如何在Godot中创建一个计时器,在给定的时间后销毁脚本的对象?我希望在一段时间后从游戏中删除子弹,以减少滞后。
有一个Timer
节点可以使用。您可以将其添加为子级,设置等待时间(以秒为单位)-您可能需要将其设置为一次性并自动启动-将"timeout"
信号连接到脚本,并在方法上调用queue_free
以安全释放Node(和子级,包括Timer
)。
如果你喜欢的话,你也可以从代码中做到这一点。所以,让我们回顾一下我刚才所说的,但与其从编辑器中进行,不如让我们看到等效的代码:
创建一个Timer
,将其添加为子级:
var timer := Timer.new()
add_child(timer)
设置等待时间(秒):
timer.wait_time = 1.0
设置为oneshot:
timer.one_shot = true
与其将其设置为自动启动(即timer.autostart = true
,不如让我们启动它:
timer.start()
将"timeout"
信号连接到一个方法。在这种情况下,我将调用方法"_on_timer_timeout"
:
timer.connect("timeout", self, "_on_timer_timeout")
func _on_timer_timeout() -> void:
pass
然后在该方法_on_timer_timeout
中,调用queue_free
:
timer.connect("timeout", self, "_on_timer_timeout")
func _on_timer_timeout() -> void:
queue_free()
您可能需要使用SceneTreeTimer
,如以下代码所示:
func die(delay: float):
yield(get_tree().create_timer(delay), "timeout")
queue_free()
请参阅Godot引擎的文档。
在Godot4中,有一种更简单的方法:
# Do some action
await get_tree().create_timer(1.0).timeout # waits for 1 second
# Do something afterwards
queue_free() # Deletes this node (self) at the end of the frame
但是,如果在_process()
或_physics_process()
函数中执行此操作,则每帧都会创建更多的计时器,这会导致在运行以下代码之前同时进行多次运行。要处理此问题,只需跟踪定时事件是否正在发生。
_process()
中具有简单攻击逻辑的示例:
var attack_started = false;
func _process(delta):
if attack_started:
print("Not attacking, attack code running in background")
return
else:
attack_started = true
prepare_attack()
await get_tree().create_timer(1.0).timeout # wait for 1 second
begin_attack()
attack_started = false
这个await
关键字适用于所有发出信号的东西,包括碰撞事件
仅供参考:在Godot 4中,yield
被await
取代,而await
实际上只是等待信号/回调完成:
await object.signal
get_tree().create_timer(5.0)
将创建一个运行5秒的计时器,然后有一个timeout
回调/信号供您使用。
要构建slay的答案。。。
在C#中,您可以编写
await ToSignal(GetTree().CreateTimer(1.5f), "timeout");`
QueueFree();