Creating Timers in Godot
In several situations, you may want to execute some logic after a certain amount of time has passed. There are three main ways to do that in Godot 4.x:
- Using a
Timer
node; - Counting the elapsed time in a node’s
_process
function; and - Creating a one-off SceneTree timer.
Let’s go through each one of these methods.
1. Using a Timer Node
extends Node
func _ready():
# Create a timer node
var timer: Timer = Timer.new()
# Add it to the scene as a child of this node
add_child(timer)
# Configure the timer
timer.wait_time = 1.0 # How long we're waiting
timer.one_shot = true # trigger once or multiple times
# Connect its timeout signal to a function we want called
timer.timeout.connect(_on_timeout)
# Start the timer
timer.start()
func _on_timeout():
# Logic to be executed after the wait time
Several of these steps can be done in the editor interface. You can add a Timer node to your scene, configure it in the editor, and then connect its signal to a function in one of your nodes. You can set the node to auto-start, which will make the timer automatically start when the node enters the tree, or you can start it manually in your code.
To start a Timer created, configured, and connected in the editor, in your code:
extends Node
@onready var timer = $Timer
func _ready():
timer.start()
func _on_timeout():
# Logic to be executed after the wait time
Instead of connecting the signal to a function, you can also await for it to be emitted in your code. This will pause the current function’s execution until the signal is emitted:
extends Node
@onready var timer = $Timer
func _ready():
timer.start()
await timer.timeout
# Logic to be executed after the wait time
It’s also possible to inline the function we’re connecting to:
extends Node
@onready var timer = $Timer
func _ready():
timer.timeout.connect(func():
# Logic to be executed after the wait time
)
timer.start()
2. Counting the Delta Time in a Process Callback
We can code our own timer, instead of using the one provided in the Timer node (you can see the current implementation of the Timer node here).
To do this, we’ll sum the amount of time passed each time the _process
function is called, and after that amount is above the wait time we want, we will execute a function.
extends Node
var wait_time := 1.0
var time_passed := 0.0
var has_timer_finished := false
func _process(delta):
if has_timer_finished == false:
time_passed += delta
if time_passed >= wait_time:
has_timer_finished = true
_on_timeout()
func _on_timeout():
# Logic to be executed after the wait time
3. Creating a One-shot SceneTree Timer
The last way to create a timer is through the SceneTree.create_timer
, which returns a SceneTreeTimer
. This timer is not a node, will auto-start, and cannot be reused.
Here’s one way to use it:
extends Node
func _ready():
var scene_tree: SceneTree = get_tree()
var timer: SceneTreeTimer = scene_tree.create_timer(1.0)
timer.timeout.connect(_on_timeout)
func _on_timeout():
# Logic to be executed after the wait time
As with the Timer.timeout
signal, you can connect it to an inline function or await
for it. A common way to use it is:
extends Node
func _ready():
await get_tree().create_timer(1.0).timeout
# Logic to be executed after the wait time