• Godot Help
  • Connecting signals from instantiated child node to parent.

Hi, I am trying to recreate a common aviation scenario, where an aircraft flies into detection range of a radar, and the receiver on the aircraft captures the characteristics of the waves that it emits. I have individual scenes for the aircraft and radar. In my test scenario, the aircraft is called "Entity1" and the radar is "Emitter". My testing scene is a 2D node called "First". The Emitter has a custom signal called entity_in_scan_range that is emitted if my aircraft enters its ScanRange node, which is an Area2D. This signal is captured in "First", which then forwards some properties of my Emitter object to the aircraft's receiver.

I am able to create this basic scenario, but for each Emitter, I have to connect its signal to "First". Is there a more automated way to do this? I would like to have every Emitter instance's signal connected to the parent node without having to manually connect them when I place them on the level. I believe I can use the .connect() method in code to do this, but I do not think I fully understood its usage.

I have added screenshots, which will hopefully make what I am attempting to do much clearer.

The "First" scene:

Script for "First":

The "Emitter" scene:

The script for "Emitter":

Seems to work when signals are manually connected:

How I'm trying to connect the signal (this is the emitter.gd script):

Method in "First" that I'm trying to call on capturing the signal:

However, this throws an error that says:
"Invalid type in function 'connect' in base 'Signal'. Cannot convert argument 1 from Nil to Callable."


EDIT (AN UPDATE):

If I duplicate my instantiated Emitter in the "First" scene and change its properties, I don't have to manually connect the signal to "First", but I do if I instantiate another "Emitter". This brings me to three questions:

  1. Is it hence better to duplicate scene instances instead of creating new ones if I want to have a common communication channel between the parent and child nodes? This way I don't need to have <X> different methods for capturing the signals from <X> different instances of the same object type.

  2. Why does this work?

  3. What am I doing wrong here? What would instead be the correct way to use .connect() instead of the way I have used it?

  • xyz replied to this.

    rohitchaoji Yeah, you need to use connect(). Keep all emitters in group emitters. At startup let First get the list of all emitters using get_nodes_in_group("emitters"). Iterate through the list and connect their signal one by one using connect(). If you need to identity which emitter sent the signal, put it in the signal argument.

    In Emitter:

    signal entity_in_range(emitter)
    
    func entity_detected():
    	entity_in_range.emit(self)

    In First

    func _ready():
    	var emitters = get_tree().get_nodes_in_group("emitters")
    	for e in emitters:
    		e.connect("entity_in_range", _on_entity_in_range)
    
    func _on_entity_in_range(emitter):
    	print(emitter)

      xyz

      Thank you! I had something similar in mind where I put the emitters in a child node of the First scene and tried calling connect on each of the objects in it. I think the mistake I made, however, was trying to call connect in the Emitter's script rather than First. I will try this out. Thanks a lot!

      • xyz replied to this.

        rohitchaoji Always connect from script that is "above" the things you are connecting, because that script has the "oversight" of the whole situation.