0 votes

So say I have the script ('button' is a button control in my scene)

func _ready():
    var test_value = test()

    print('you should only see this after test() fully finished')
    #this means test_value should now be 'DONE'

    print(test_value)
    #however 'DONE' is never printed! Instead, I get '[GDFunctionState:546]'

func test():
    print('started test')
    yield(button, 'pressed')
    print('finished test')
    return 'DONE'

How do I stop this kind of asynchronous behaviour? Reminds me of JS promises except it isn't.

I also tried doing while test_value extends GDFunctionState: continue to try and stall execution until I get my test_value...however, doing this just hangs my game, I only see the Godot logo and it keeps loading forever :(.

Any help is greatly appreciated, I've wasted tons of time on this & still can't solve it.

in Engine by (45 points)

1 Answer

+3 votes
Best answer

Your test function turns to a coroutine if you use a yield statement inside it. So when you call the test function, Godot runs the test function code until it hits the yield statement. At this time a coroutine manager will stop the execution of the function and save the state of the function until the yield is qualified.
Resuming takes sometime depending on the signal used in the yield. At the time yield is qualified, the coroutine manager will run the remaining code in the function inside it's own scope.

Always remember that yield is function scoped. When the engine hits a yield, the function execution is actually complete. So it returns and runs the next line in the code.

You have to call the remaining things from the test function itself after the yield.

by (750 points)
selected by

I guess I'll just copy the body of the test function & paste it into _ready(). This is the model I had in the start. However, I was trying to make my code more modular & clean.

Is there a way to encapsulate blocks of code that execute to the end (& include parts that wait for input there)? Or do I have to spaghetti code through this? Thanks btw!

You can make those sections in another function and call that function after yield.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.