I'm so frustrated, i can't seem to figure out how to work with signals when it comes to scenes instanciated from code in GODOT 4. I tried all sorts of things, but cannot seem to grasp my head around it.

I can fine figure out how to connect and listen to signals when the scenes are present in the game tree. It's driving me mad, I searched a lot in forums but with no luck. So i final gathered the courage to write in this forum. So here we go:

I have a Game scene with different scenes it in.

-I have a SkeetShooter scene which throws skeets for the player to shoot.
--The SkeetShooter scene instanciates skeets from code (bacially a enemy in other terms)
--When the bullet (which are also instanciated from code) hits the skeet this function is called

func _on_body_entered(body):
	print("bullet_area2d are hitting: ", body.name)
	#destory bullet
	queue_free()

The skeet has the following signal and emition of it when it destoyed

signal increaseScore

func _exit_tree():
	print("skeet destoryed")
	increaseScore.emit()

I have GUI scene which i want to listen to the increaseScore.emit() which are triggered in the skeet scene/node when it's destoyed.
This is the part i cannot figure out. How to i listen to signal emitted by skeets?
I might be worth telling that i can have as many skeets in a scene there can be 1 and there can also be 20.

extends CanvasLayer

var score = 0

func _ready():
	update_score_label()
	$ScoreLabel.text = str(score)
	#how to i dynamically connect and listen to all skeet which are instanciated when they are generated on the fly
	connect("increaseScore", on_listen_to_skeet_increasce_score_emit)
	
func _process(delta):
	pass


func update_score_label():
	score = score + 1
	print("we run the update score function in the gui scene")
	$ScoreLabel.text = str(score)


#i want this function to be called every time any instanciated skeet are emitting the increaseScore.emit() from the skeet script
func on_listen_to_skeet_increasce_score_emit():
	update_score_label()
	print("we have caught the skeet increaseScore SIGNAL!!!")

I want to add if it was a normal program written in python, C# or any other laungauge i would just add a reference in the skeet script to the "gui" object and then call the function from the skeet. But as i read it and understand it, godot aims not to create to many dependencies and therefore work with signals. If thats not the case I'm also open for how to add a reference from the skeet script to the "GUI" scene and call the function from there if thats a better solution and someone have suggestion for implementation of that.

Hope someone can help me figure this out 🙂. Since I'm not ready to loose my sanity 🙂

Update after post: Also the "code blocks" in this post dosen't seem to work for me. Im using the ``.. 😛 so im sorry for making this hard to read..It's my first post......
// Lars

    lazerlars
    First way :
    make yourself a node called SkeetContainer, spawn the Skeet under it and in the ready function of your skeet, connect the skeet via code this way :

    signal increaseScore
    func _ready():
           if increaseScore.is_connected(get_parent().increaseScore) == false:
    		  increaseScore.connect(get_parent()increaseScore)

    then in your new SkeetContainer, do the same thing. connect a signal to your base node (in your case it's Level and have a receiving function in Level transmit the info to your GUI.)

    Second Way :

    Another way you can do it is "init" your Skeets.

    So you start in your Level node and call a init() function which contains your GUI reference then go down the tree until you instance your skeet

    then in your skeet, you declare a blank reference like this 🇦

    var gui_reference = null
    
    func init(_gui_reference):
          gui_reference = _gui_reference

    then you can just call whatever function in your gui_reference from the skeet before destroying it.

      lazerlars Conceptually, you shouldn't think in terms of instances or signal listeners because those actually do not exist at runtime.

      • There is only one big tree of active nodes at runtime, called the scene tree.
      • You can inspect the current state of the scene tree at runtime by switching to "Remote" in the scene tab.
      • When you "instantiate" a scene, its nodes are just "unpacked" and appended to that main tree at specified place as a branch. Instances as entities do not exists.
      • You can connect any node to any other node in that tree, from a script anywhere else in the tree, given that you have proper relative paths to source and destination nodes of that connection.
      • Signals are simply function callbacks. Establishing a signal connection is in fact just passing a callback reference to the signal emitter.

      lazerlars I want to add if it was a normal program written in python, C# or any other laungauge i would just add a reference in the skeet script to the "gui" object and then call the function from the skeet

      That's precisely what it is in Godot. When you call connect() you pass a reference to the function/method that will be called when the signal is emitted (either explicitly by your code or by some built-in event)

        Thank you for both answers. This made me realize how is working. I ended up doing the implementation like this:

        in my skeet script:

        signal increaseScore
        
        func _exit_tree():
        	print("skeet destoryed")
        	increaseScore.emit()

        in my skeet_shooter script:

        signal notifyScoreIncreaseToGUI
        
        func throw_skeet():
        	print("throwing skeet!!")
        	var skeet_instance = skeet.instantiate()
        	#connect to the signal in the skeet instance and call throwSignal method everytime we catch a signal emit from 
                 a skeet
        	skeet_instance.increaseScore.connect(throwSignal)
        	skeet_instance.position = $Marker2D.global_position
        	get_tree().root.add_child(skeet_instance)
        	print($Marker2D.global_position)
        	#letsemit.emit()
        
        func throwSignal():
        	print("we are throwing signal, SUPPPPPPER")
        	notifyScoreIncreaseToGUI.emit()

        And then in my Level scene where i both have my GUI and Skeet_Shooter node i connected the notifyScoreIncreaseToGUI to the level script via the node inspector:

        func _on_skeet_shooter_notify_score_increase_to_gui():
        	print("notifyer is run, lets update score ma dudes")
        	$GUI.update_score_label()

        Thank you so much Loxyrak and xyz for taking the time to answer my question and clairfy the things for me. I'm very grateful and I'm so happy to finally understand this 🙂 🙂 🙂 🙂