How to make a part of a script always repeat (in loop) after X seconds?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ralime
:warning: Old Version Published before Godot 3 was released.

I need to ask: are you used to structured programming?

If not, maybe you can look for some introductions to python to learn how to use things like functions (you can find a couple recommended in the Q&A).

eons | 2017-05-22 15:50

:bust_in_silhouette: Reply From: henriquelalves

First, I understand the title of the question is pretty much self-explanatory, but you should describe your question better. For example, what do you mean as a “part” of the script? Is it a method? Are you trying to run a whole section of it? How many approaches have you tried before asking the question?

Now, let’s think about the game loop. You know you want to keep repeating a piece of code, so intuitively we can think on writing that code on the game loop (process or fixed_process) and have our way on it. But to repeat something every X seconds, we would have to get information on Time spent each loop; we could use Godot timer node, but usually I like to do this on the script I’m working with by simply storing time spent each loop (that’s the ‘delta’ that process and fixed_process gives you), and when this timer is bigger than a threshold, reset it and run the piece of code I want. For example:

timer = 0
timer_limit = 1000 # in miliseconds

fixed_process(delta):
..timer += delta
..if (timer > timer_limit):
....timer -= timer_limit
....# REST OF THE CODE

:bust_in_silhouette: Reply From: Zylann

You can also use a Timer:


func _ready():
	# Create a timer node
	var timer = Timer.new()

	# Set timer interval
	timer.set_wait_time(1.0)

	# Set it as repeat
	timer.set_one_shot(false)

	# Connect its timeout signal to the function you want to repeat
	timer.connect("timeout", self, "repeat_me")

	# Add to the tree as child of the current node
	add_child(timer)

	timer.start()


func repeat_me():
	print("Loop")

Thank you!
This worked flawslessly for what I needed :).

  • Doing some coastal theme and needed to extend the background sound with additional sounds (like seagulls) do let them hear themselves every now and then. So I extended the script with some randomize(). Only “error” I have is that the first time, it plays it 2 times after each other, even if the first random number is 10 (for 10 seconds).
    Still need to add something so it chooses a rondom sound from a list/array/variable to make it even more diverse -

eyeEmotion | 2020-04-24 15:34

:bust_in_silhouette: Reply From: Lightbulb

you can use the one line timer at the end(or start) of your function and , and then recall the same function at the end.

func example():
     stuff
     yield(get_tree().create_timer(timeBetweenCalls), "timeout")
     example()

Calling the same function again and again (recursion) might slow down the operation due to calling procedure. Iteration seems better here.

GaloIsProgramming | 2021-12-18 21:25

:bust_in_silhouette: Reply From: idbrii

You can use a loop and yield to a timer:

var delay = 1 # seconds
var count = 0
while true:
	await get_tree().create_timer(delay).timeout # Godot 4 yield syntax
	count += 1
	printt("Repeat!", count)

Using a loop is simpler than recursion, allows you to have local state (count in the example), and you don’t risk hitting a stack size limit.

Note that create_timer() doesn’t create a Timer node. It creates a SceneTreeTimer which should be more efficient that repeatedly spawning a Timer node. (Although Zylann’s answer using a Timer node is a good one since it only spawns the node once.)

For Godot 3, you can use the yield syntax from Lightbulb’s answer:

while true:
	yield(get_tree().create_timer(delay), "timeout") # Godot 3 yield syntax
	print("Repeat!")