Yield in child script does not retrieve signal from parent script

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

Hello everybody !

I have a very weird problem in Godot.
I have two scripts : One is “Human.gd” and is a parent script to the second which is “Enemy.gd”.

My parent script "Human.gd" has a signal “move_finished”, which is emitted in a function called "move", which exist to move my KinematicBody2D from its actual position to a point given (in a smooth way).

Since it is not a teleportation, it takes time. Thus I need something to tell functions using “move” that they are arrived where they want. That something is my signal.
I use a yield to wait the signal.

This is what it looks like in the parent :

func move(point,tolerance):
  var distance_to_go = position - point
  distance_to_go = distance_to_go.abs()
  var tolerance_v = Vector2(tolerance,tolerance)
  var direction = get_orientation(point)
  while distance_to_go > tolerance_v:
	  move_and_slide(direction * velocity)
	  animation(direction.round())
	  yield(self,"new_physics_frame")
	  distance_to_go = position - point
	  distance_to_go = distance_to_go.abs()
  emit_signal("move_finished")

And the usage in the children :

move(path[i],0.01)
yield(self,"move_finished")

Now here’s the problem (because everythig was too perfect) :
yield doesn’t seem to retrieve the signal. Thus, my whole script is blocked in the yield part, and it never continue.

Someone has an explanation ?
Thanks in advance ! :slight_smile:

I’ve never seen the signal “new_physics_frame”. What object emits it?

null_digital | 2019-12-04 21:55

Oh, it’s a custom signal sent by the script “Human.gd” at each physical frames.
I use it to scale the animation properly.
I know it’s bad since I could use the official signal sent by the engine itself but it works for now so meh.

kisis | 2019-12-05 08:00

:bust_in_silhouette: Reply From: null_digital

Your logic works:

extends Node
class_name Ba

signal a_frame
signal done

func _process(delta):
	emit_signal("a_frame")
	pass

func test():
	
	var itx = 0
	while itx < 10:
		yield(self, "a_frame")
		itx += 1
		print("itx ", itx)
	
	emit_signal("done")
	pass

extends Ba

func _ready():
	test()
	yield(self, "done")
	print("Im done")
	pass

Will output:

itx 1
itx 2
itx 3
itx 4
itx 5
itx 6
itx 7
itx 8
itx 9
itx 10
Im done

The only thing I can think of is “newphysicsframe” signal isn’t being emitted properly. Is it emitted from a process() or fixedprocess()? Are there conditions for it to be emitted?

EDIT: depending where you’re calling move() from, you’ll have multiple coroutines altering the state of your object at the same time.