Pickup crashing when collected; possibly caused by while loop

Here is the code:

func _on_body_entered(body):
animated_sprite.play(“collected”)
while animated_sprite.is_playing():
pass
queue_free()

Godot crashes when i pick it up. Can anyone tell me why and how to fix it?

Consider waiting for the animation to finish instead. Make absolutely sure your animation doesn’t loop, because in that case the signal never fires.

You are blocking the thread with your loop. _on_body_entered is executed in the same thread as the animation is played. That is, the animation will only continue at some time after the _on_body_entered is done. But it is never done, because the animation cannot continue :wink: .
No matter how short your animation is or if it is looping, it’s always an endless loop.

To solve this, you could use coroutines as @TokyoFunkScene mentioned. By using await you make your function asynchronous, which allows the execution of the caller to continue.

An alternative, but overkill for this situation, is to have your loop in another thread. But there is a lot to consider with mutli-threading (deadlock, races, thread-safety, …).

1 Like

I think the simplest solution is to start the animation in _on_body_entered, but also set a boolean variable named like ready_to_free=true.

Then, in _process or _physics_process, do the queue_free there after the animation is complete:

if ready_to_free and not animated_sprite.is_playing():
    queue_free()

The await solution is also good, but I think putting logic in _ready, _process, _physics_process, and signal handlers is the most straightforward way to understand what your game is doing.

Always remember than ANY function called from Godot during runtime (outside of a coroutine or background thread), must complete quickly or the game will freeze. If you have to wait for something, wait for it to happen in a later frame, which means a later call to _process or _physics_process.

1 Like