I'm using a yield inside of a function like this:

unit.play_turn(action)
yield(unit,"action_finished")
next_unit_in_queue()

But the code after the yield never gets executed even though the signal is being emitted. I created a function connected to this signal to check and it is called at the right time, but the yield doesn't break I have used yields in this manner before and never encountered this problem? Does anyone have any ideas of what may be causing this?

How are you checking to see that the action_finished signal is being emitted?

Also, is the signal emitted after the play_turn function is called? If not, it could be that the signal is being emitted before the yield statement, leading the code to pause at the yield waiting for a signal that already arrived.

it's just a guess, but maybe with deferred call, I'm still investigating its use, but if I'm not mistaken it calls a function to the function outside the tree or when it finds the right time

example:

# ...

unit.call_deferred("play_turn", action)
yield(unit, "action_finished")
next_unit_in_queue()

#...

If you know its use well and I am wrong, please correct me.

@TwistedTwigleg said: How are you checking to see that the action_finished signal is being emitted?

Also, is the signal emitted after the play_turn function is called? If not, it could be that the signal is being emitted before the yield statement, leading the code to pause at the yield waiting for a signal that already arrived.

play_turn() calls the signal action_finished at the right moment I checked this connecting action_finished to another function to print and the result was like this:

#CombatManager.gd

        func create_unit():
          var unit :Unit = Unit_scn.instance()
          unit.connect("action_finished", self, "action_finished_foo")
        
        func action_finished_foo():
          printerr("action_finished signal received")
        
        func turn_preparation(unit):
          printerr(" - turn_preparation - ")
          unit.play_turn(action)
          yield(unit,"action_finished")
          print("yield resumed")
          next_unit_in_queue()
    
    func next_unit_in_queue():
      printerr(" - next_unit_in_queue -")

#I'm never able to make the indentations look right in the forums...

#Unit.gd


func play_turn(action):
#  I commented everything else just to test the signal
  emit_signal("action_finished")

The output was like this:

 - turn_preparation -
action_finished signal received

And I say was because I "fixed it" since then but, I didn't change anything related to the signals I cleaned a bit the code and it started working again, but the output points out to something going wrong with the signals right? Maybe a bug but I couldn't reproduce it again.

@TheDiavolo said: it's just a guess, but maybe with deferred call, I'm still investigating its use, but if I'm not mistaken it calls a function to the function outside the tree or when it finds the right time

I haven't used it but what for what I read it just ensures this is called on an idle frame so it doesn't conflict with other functions that may be running every frame. But I don't think this would help in my case. Anyway I already "fixed it" but I don't really know the reason why it was failing in the first place so it is the worst kind of fix

As @TheDiavolo pointed out call_deferred fixes the problem but I didn't understand why until the user Andrew Wilkes in the Godot Q&A found out that yield returns if the signal is received within the current frame is this the desired behavior?

I'll have to read the documentation again because I don't remember anything about this.

Not using call_deferred or yielding until the next frame before emitting the signal makes yield return instead of executing the rest of the function:


    func _ready():
    	connect("button_down",self,"_on_button_pressed")
    	foo_test()
    
    func foo_test():
    	print("foo_test")
    #	call_deferred("foo_emit")
    	foo_emit()
    	yield(self,"foo")
    	print("yield resumed")
    	foo_print()
    
    func foo_emit():
    	print("foo_emit")
    #   yield(get_tree(),"idle_frame")
    	emit_signal("foo")
    
    func foo_print():
    	print("success")
a year later