Yielding with a timer

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Lavialee

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…

:bust_in_silhouette: Reply From: Gluon

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.

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 :))

Lavialee | 2022-11-23 16:29

Yes you are exactly correct.

Gluon | 2022-11-23 16:32

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?

Lavialee | 2022-11-23 16:41

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)

Gluon | 2022-11-23 18:12