Await for signal in same node does not work

Godot Version

4.4

Question

I have a node that has a signal defined:
signal rotation_finished()

in ready, I connect it to same node
self.rotation_finished.connect(self._on_rotation_finished)
(tried to do it through editor, and without “self” as well, but result was always the same)

Method 1 has
(… some animations…)
print(“1”)
rotation_finished.emit()

Method 2 has
method1()
print(“2”)
await rotation_finished (tried with self too, but same result)
print(“4”)

I have on_rotation_finished defined as well, with print(“3”) statement.

when I run it, prints 1,2,3 happen easily, but godot keeps waiting forever on await statement. Generally, I have been using signals between different nodes and it worked ok. This is first time I encounter such issue and I suspect that problem is related to sending and awaiting signals in same node.

Is there something I am doing wrong? Or maybe I should not use signals and use some other method to wait for method 1 to finish while inside method 2 ?

The issue comes from the fact that you are awaiting a signal after it has already fired. If we write your whole sequence flat, it would be:

print(“1”)
rotation_finished.emit()
print(“2”)
await rotation_finished
print(“4”)

You emitted the signal first, and then you await it. The engine doesn’t know that the signal was emitted already, it will await forever until you emit the signal again.

You can await a method as well, this way the method becomes a coroutine. I’m not sure in what sequence you want your code to run exactly, because your example is a bit misleading, it would be best if you shared your actual code. In general when you do something like that:

func method1() -> void:
	print("1")
	method2()
	print("3")

func method2() -> void:
	await get_tree().create_timer(1.0).timeout
	print("2")

This will print

1
3
2

But when you add the await keyword before calling method2()

func method1() -> void:
	print("1")
	await method2()
	print("3")

func method2() -> void:
	await get_tree().create_timer(1.0).timeout
	print("2")

This will print

1
2
3

When you have some animations within your functions that you want to await - you can await these too before proceeding. This way, you can make a chain of events that all await each other before moving on.

Here are some more information about coroutines, highly recommend to check out.

thank you , this was very helpful

Always happy to learn something new - awaiting whole methods is great suggestion. I checked and it already works , now will read some more on coroutines

I realize @wchc gave you an informative answer, and if that’s all you need, feel free to ignore this. But I think it’s much simpler to do what you want. I am assuming that you want something to happen after the rotation is complete. In which case you do not need an await or coroutine.

signal rotation_finished

func _ready() -> void:
	rotation_finished.connect(_on_rotation_finished)

func rotate() -> void:
	print("Rotation started.")
	rotation_finished.emit()

func _on_rotation_finished() -> void:
	print("Rotation complete.")
1 Like