First argument of yield() not of type object.

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

Error: First argument of yield() not of type object.

on

yield(get_parent()._find_movement(), "completed")

or

yield(get_node("..")._find_movement(), "completed")

The tree is simple:
workspace # root
l_ Player
l_ AI #where the error is.

I don’t understand why this isn’t working. It’s acting like my root node isn’t even there.
I’ve even tried get_node("workspace")._find_movement and it act likes the node doesn’t exist.

Does the function _find_movement() return something? I think the first argument to yield() needs an object of some kind.

Ertain | 2019-12-11 00:45

The function has a bunch of if statements that change a global variable based off of conditions met, but I never did a hard return of anything. Do I need a return value for this yield statement?

Dumuz | 2019-12-11 01:23

:bust_in_silhouette: Reply From: Ertain

From what I’ve read of the yield() function, your _find_movement() function may have to emit the completed signal for the base function to resume. Either that, or call resume() from within the _find_movement() function.

The Doc’s Coroutines with yield infer that the completed signal is something built into the yield function. When they "transition into an invalid state".

Unless I’m totally misunderstand the usage and example in this doc, which is very much quite possible, cause I’m super new at this. The error that I was getting seems to imply something it wrong with the get_node, the object aspect of the 2 arguments of yield. The game doesn’t even play the function in the parent node at all. It was just seems to stop, when trying to access the node.

I’ll try to add a resume signal and see if that helps.

Dumuz | 2019-12-11 15:38

:bust_in_silhouette: Reply From: i_love_godot

Like Ertain mentioned, yield needs an object first, then the string of the signal you’re listening for:

yield(object_that_emits_the_signal_we_want, "signal_we_want")

If get_parent()._find_movement() is being passed as the first argument to yield, it needs to return an object.

Thanks for responding I_love_godot, I appreciate the help. Bare with me as I’m still new to coding.

I thought a function is considered an object?

in this doc example, the yield seems to have no problem accessing a function in place of an object argument. Then there is a completed signal it waits for. The doc’s imply that once the func button_func(): is finished, the yield from my_func() would automatically see that its GDstate changed and then resume itself. Is this correct? Or am I way off here?

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

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

Thank you again!

Dumuz | 2019-12-11 16:01

So you are calling yield from within _find_movement() too? And what signal is _find_movement() listening for, and is it being emitted?

i_love_godot | 2019-12-11 16:13

At current, _find_movement() has no yield in itself and not listen for or emit any signals.

I just have a function yielding to it via: yield(get_parent()._find_movement(), "completed")
Or something like this.

Dumuz | 2019-12-11 16:28

Yes, so to solve the error you either need to return an object, or yield within the _find_movement() function which would automatically return it’s frozen state.

i_love_godot | 2019-12-11 16:33

I see now. So, I can’t simply put a return at the end of an if statement inside _find_movement()? Could I return a Vector3? or a Null?

or do I need to call a resume()?

Dumuz | 2019-12-11 16:40

If you are going to return from _find_movement() then you need to return a signal emitting object, or yield (which automatically returns the state which will emit “completed”)

It may be easier to explain what it is that you’re trying to achieve. Also, if you can post a larger code sample to get a better picture that would be helpful too.

i_love_godot | 2019-12-11 16:45

So I have this function:

func _movement1():
	if y == 0:
		return null
	yield(get_parent()._find_movement(), "completed")
	var target = translation + direction
	$Tween2.interpolate_property(self, "translation", translation, target, 1, Tween.TRANS_LINEAR, Tween.EASE_IN)
	if not $Tween2.is_active():
		$Tween2.start()

then in the parent node I have:

func _find_movement():
	if $AI.command == ["right"] and $Player.command == ["left"]:
		if distancebetween == 5:
			$Player.direction = Vector3()
			$AI.direction = Vector3()
		if distancebetween == 10:
			$Player.direction = Vector3(0,0,2.5)
			$AI.direction = Vector3(0,0,-2.5)
		else:
			$Player.direction = Vector3(0,0,5)
			$AI.direction = Vector3(0,0,-5)
	else:
		return _proceed_as_normal()
			

func _proceed_as_normal():
	$Player._getdirection()
	$AI._storage()

Hope that helps.

Dumuz | 2019-12-11 17:23

It looks like you’re wanting to wait for the _find_movement() function to complete before carrying on with the _movement1() function. But from what I can see, the code seems pretty linear anyway and will be executed in sequence.

Have you tried removing the yield call on line 3 of the _movement1() function? It doesn’t seem necessary and is failing because neither _find_movement nor _proceed_as_normal actually yield or return objects. Also, _find_movement only explicitly returns sometimes, based on the if else.

i_love_godot | 2019-12-11 17:40

Well I have two node with that same movement code calling to _find_movement(), and _find_movement() is longer than that, there’s 4 other identical if/else statements that like first section, I just thought it would be redundant to post. Without the yield, the two children: Player and AI, don’t seem to access the function at the same time and creates movement that doesn’t seem to be what I’m looking for. So I made _find_movement() as kind of a pre-calculator for the tween. I figured a yield function would be good cause it would process how to move based off the distance from each other, then send out the necessary movement variables.

Dumuz | 2019-12-11 17:59

:bust_in_silhouette: Reply From: MeatTheJuicy

I believe i may have found the reason why this happens, on my end the func in the first argument of yield was being completed seemingly too fast for the yield to register.

The func in question:

func example_func():
    #in this situation condition is true
    while condition == false:
	    #rest of code

However, the error would not replicate after adding a deliberate period of wait:

func example_func():
    #in this situation condition is true
    while condition == false:
	    #rest of code
    yield(get_tree(), "idle_frame")

This is the correct answer!

I could not figure out why this started happening all of a sudden on export, and it’s because the first thing I did in X function was to return false if there was no file at some path. This is always the case the first time the program is run, but never again.

TLDR, my function returned a value way too fast and yield couldn’t register. I solved by adding a yield(get_tree().create_timer(0.001), "timeout") in the function for that case.

scrubswithnosleeves | 2022-06-02 21:22