0 votes

I am trying to figure out yielding and it isn't working how I expected it to and I cannot figure out what I'm doing wrong.

I have a function in the main game node that is called on a specific signal. If the conditions are met I want it to wait until an animation is finished and then continue with the function.
I tried to use (browse is the animation node)

yield($browse, "animation_finished")

which didn't work.

So I wanted to experiment further and while

yield(get_tree().create_timer(1.8), "timeout")

works, when I made an actual Timer called Yielder as a child of the main node, set it to 1 second and tried to call it

yield(get_node("Yielder"), "timeout")

it didn't continue the code from which I'm yielding.

I have no clue if it's something completely different in my code but I'm very confused rn...

Godot version 3.5.1
in Engine by (21 points)

1 Answer

+2 votes
Best answer

Well a node would never have a timeout signal. The function may create a timer but you have told yield to wait until the function itself sends a timeout signal which it never will.

Try creating the following:

func _ready():
    var TY = testyield()
    print("ready print")
    TY.resume

func testyield():
    print("first test")
    yield()
    print("second test")

if you watch the printout then you will find it will print first test, then ready print, then second test. If you remove the TY.resume it will never run second print.

If you want a timer to set this off you need to connect the timer to a function which runs resume on your yield.

by (3,321 points)
selected by

So if I understand correctly - the _ready function will create a TY object of the testyield function, which will run automatically (since it was created), until it hits the yield() which then goes back to the _ready function and runs from after it created the variable, prints and then resumes TY from the point where it yielded.

Whereas if I just did this

func _ready():
    var TY = testyield()
    print("ready print")

func testyield():
    print("first test")
    print("second test")

am I correct in assuming it would print first test, second test and afterwards return to the _ready function since everything in the variable finished?

Thank you so much, I'm a beginner and this is kind of hard to wrap my head around :))

Yes you are exactly correct.

And one last question on which I'm confused - what if I wanted to implement a custom signal? Let's say I'm in testyield() and wanted to wait until it gets a signal and then continue _ready?

Well there are a number of ways to do this and different people may choose different methods but if you are looking for something simple to understand perhaps try the below code as an example

var exam = yieldtest()
var Ti

func _ready():
    exam
    timer("_yieldrun")

func yieldtest():
    print("yieldtest 1")
    yield()
    print("yieldtest 2")

func _yieldrun():
    print("Yieldrun Print")
    exam.resume()

func timer(yiel):
    print("timertest")
    Ti = Timer.new()
    Ti.autostart = true
    Ti.one_shot = true
    Ti.wait_time = 2
    Ti.connect("timeout", self, yiel)
    add_child(Ti)
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 Frequently asked questions and 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 [email protected] with your username.