Luis Carli

I'm a designer and creative coder making video-games [more]

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:

  1. Using a Timer node;
  2. Counting the elapsed time in a node’s _process function; and
  3. 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

Published 2024.02.10

Get New Game Updates via Email!
No spam, no intermediaries, just the good stuff delivered straight to you.