Yield doesn't accept method as argument

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

When I try to call function using yield(foo(), "completed"), runtime error appears: First argument of yield() is not of type object, but example from here shows that it should work:

func my_func():
    yield(button_func(), "completed")
    print("All buttons were pressed, hurray!")


func button_func():
    yield($Button0, "pressed")
    yield($Button1, "pressed")

How can I call a method using yield function?

My code:

extends Node2D

func b():
	print("He")

func a():
	print("Ho")
	yield(b(), "completed") # error

func _ready():
	a()

I’m using godot 3.2.2 stable

:bust_in_silhouette: Reply From: njamster

The example in the docs works because button_func() uses yield as well and yield returns a GDScriptFunctionState - which happens to be an Object.

Consequentially your code doesn’t work becauseb() does not return an Object. If you don’t mind one frame of inactivity you could do it like this:

func b():
	print("He")
	yield(get_tree(), "idle_frame")

func a():
	print("Ho")
	yield(b(), "completed")

func _ready():
	a()

It may also be of interest to those running into this issue for the first time, that a function that can sometimes yield or not can be handled using the GDScriptFunctionState that returns.

If the function doesn’t yield it will return either null or its given value. This can be checked to safely handle yielding for its completion when the function does yield.

With the code below, experimenting with different delay parameters will show this off.

extends Node2D
    
func _ready():
	
	var result = my_func()
	
	if(result is GDScriptFunctionState and result.is_valid()):
		print("awaiting my_func()")
		yield(result, "completed")
		
	print("done")
	
func my_func(delay = 1.0):
	
	if(delay > 0.0):
		yield(get_tree().create_timer(delay), "timeout")

avencherus | 2020-08-29 10:42