Hi everyone, first time posting here. I was going to go to Discord but thought it's better to ask somewhere that can turn up on search engines for future confused game devs.
I've got a parameterised signal listener like this:
func _on_movement_to_exit_complete(character: Node2D):
var f = func():
print("_on_movement_to_exit_complete: "+str(character))
var dungeon_tilemap: TileMap = dungeon_control.get_current_dungeon_tilemap()
var party = dungeon_tilemap.get_node("Party")
var initial_party = dungeon_control.get_parent().get_node("InitialParty")
party.remove_child(character)
initial_party.add_child(character)
if party.get_child_count() == 0:
for party_member in initial_party.get_children():
var tilemap_movement: TilemapMovement = party_member.get_node("TilemapMovement")
print("Disconnecting movement finished listener for "+str(party_member))
tilemap_movement.disconnect("movement_finished", _on_movement_to_exit_complete(character))
load_next_level()
return f
Basically, if all the party members have exited the level (and been removed from the 'party' node) I want to disconnect this movement_finished
signal from _on_movement_to_exit_complete
. But when I try this I get an error:
E 0:00:07:0777 GameControl.gd:80 @ <anonymous lambda>(): Disconnecting nonexistent signal 'movement_finished', callable: <anonymous lambda>(lambda).
<C++ Error> Condition "!s->slot_map.has(*p_callable.get_base_comparator())" is true.
<C++ Source> core/object/object.cpp:1331 @ _disconnect()
<Stack Trace> GameControl.gd:80 @ <anonymous lambda>()
TilemapMovement.gd:23 @ _on_animation_finished()
Why doesn't it think movement_finished
exists? Is there something wrong with disconnecting signals from inside their listeners? And is there another way of doing this? (Maybe something like a signal that fires once then disconnects?)
This is in Godot 4 by the way.
Also, is there a way to make the posting box wider in the programming.dev web frontend? It's really hard to work with pasted code here!
There are a couple of issues with this line:
Firstly, you're using the old Godot 3 API. You'll want to do this instead:
Secondly, the fact that you have parameterized anonymous functions as listeners makes things a little tricky. Let's say you call
signal.connect()
and pass a parameterized listener. Later, when you callsignal.disconnect()
, you have to pass it the same function. Calling_on_movement_exit_complete()
with the same arguments returns a different (identical) function. There are a couple of ways you can work around this. A common solution would be to store your own references to the listeners for later use. something like this:I hope that makes some sense