working on Godot 4.2
I ran into an issue and wanted to share a solution that worked for me in case anyone else ran into this problem. This felt very specific and most tutorials I’ve watched don’t really talk about custom signaled instanced objects or the code snippets didn’t work for me.
Tutorial:
In this example there are two scenes
The Listener and the Signaler.
An example of an instanced Signaler used in practice would be something like a bullet or projectile hitting an enemy. If the bullet hits the enemy then the bullet(Signaler) will emit a signal that will tell the Listener to do something. For example a function that calculates damage. The triggers here are only emulating that function as the example.
The objective is to instance the Signaler into the Listener scene. The only thing not shown here is a 2D rectangle that shows up as a proof that it was successfully instanced. That rectangle is a child/ subordinate of the Signaler.
The rectangle is not really important here, I just wanted something to confirm that the instance worked.
The Listener launches the functions while the Signaler waits for something to happen. In this case waiting for Trigger 1 or Trigger 2 which are initiated by pressing the “spacebar” or “S” key respectively. When that happens it will emit a signal to proceed with a function on the Listener’s side.
I created two custom signals inside the Signaler scene:
signal hi_square_signal
signal square_info_pass_signal
The first one will be attached to a function that just says “I got the signal” if triggered.
The second one takes the value (in this case an integer) then does something with that passed value. In this case printing it to the console.
I like to make custom signals to keep things organized for readability.
I then place the .emit() function where I want the signals it to trigger. Which is after either button is pressed for the desired signal to be launched.
This would be if the bulled collided with something or an enemy
Back on the Listener’s side I created a function to instance the Signaler.
When the “Initializer” (A button) is pressed then it creates an instance of the Signaler. First by attaching it to a new variable. The referenced scene is at the top to be referenced
const SIGNALER = preload(“res:/Signaler.tscn”)
This would be like referencing the bullet scene and getting it ready to be fired
Then I attach the ability for that object/ node’s Signals to trigger a function on the Listener’s side.
signaler.hi_square_signal. connect(hi_square.bind())
signaler.square_info_pass_signal. connect(square_info_pass.bind())
This tells the bullet what to do when it hits
Here the signals are attached to those specific functions. Interestingly I’ve seen a lot of ways to do this, but the .bind() worked well for me. The graphic attached to this thread hopefully helps illustrate the overall construction of this line of code.
After attaching the signals to the function it will be added to the scene when the Initializer is pressed.
This would be when the bullet is fired and now exists within the scene. This can still be launched multiple times. But I only need one here
The final outcome is that it prints out “I got the signal” and “6”. This doesn’t happen if the Signaler is not instanced first. With the 6 being the passed value into the square_info_pass function.
This would be an example of using the function to pass a damage value to be calculated or to launch an effect of some kind after the bullet hit.
There are likely other ways to do this so if there is anyone else with more information feel free to share. I just wanted to show this test I did since I had a hard time looking up this information and getting it to work.
I hope that it helps someone out there o7