How can I connect to a signal which was emitted from a separated scene.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Idleman

How can I connect to a signal which was emitted from a separated scene. For example, there is fireball scene, it is instanced to play scene when a key is pressed. Once the fireball was fired and got destroyed, it emits a signal. How could I connect to the signal in the script attached to the player scene? I have tried use $absolute node path.connect in the player scene but it tells me node not found. Is there any ways to get connect to the signal from the fireball scene? Thank you.

:bust_in_silhouette: Reply From: p7f

there are many ways to do so, depending on your implementation. For example, in my game, i create fireballs in the player’s script. So i instance a firebal, and connect it right away, and then i add it to the level. Something like this in the player’s script, when you shoot the fireball:

# FireBall was preloaded before
fireball = FireBall.instance() 
# on_fireball_finished is a method defined in players script
firefall.connect("finished", self, "on_fireball_finished")
# add fireball where it belongs
# change fireball's position if needed after this

However, you could also have a Global script attached as an autoload, and have a reference to the player there. Anytime you instance a fireball, you could connect to the player on the fireball’s ready:

# Fireball's ready
func _ready():
    connect("finished", Global.player, "on_fireball_finished")

or something like that. If you provide a test project, i can help you further.

The first one works for me, thank you. As a new comer to Godot, some times is quite confusing with the relationship of Nodes, Scripts, and Scenes, guess it will take some time and practise to get a better understanding. Thank you very much for your help.

One more question, in my game, I want to have a charge state, when press and hold down a key, the player stays in the state. When the key is release (or not longer be hold), the play goes to a normal state. In order to trigger the state change, is Input.is_action_pressed a good way to go with? I tried this, but the behaviour is less than reliable, I am not sure if use other options like input(event) will be better. It would great to get some advise, thank you.

Idleman | 2020-07-09 06:16

Hi! I saw your other question today. I usually use Input.is_action_pressed in process if i only have to check that key in certain states. I use _input(event) for keys that should trigger an effect regardless the current state. I always found that reliable. Ill look at your other post today and see if i can help.

p7f | 2020-07-09 12:29

:bust_in_silhouette: Reply From: cgeadas

Usually I use cascading signalling. It gives me flexibility to move things around and not lose the connections or break things much. Better yet, it allows me to change the code for leaf nodes without main processing nodes noticing.

Something like:

(processing node)
connect signal A from 1
connect signal A from 2
  | - (node 1)
  |    connect signal B from 3
  |    and emit signal A
  |     | - (node 3) ...
  | - (node 2)
  |    connect signal B from 4
  |    and emit signal A
  |     |- (node 4) ...

This way, my processing node doesn’t care for node 3 or 4, but processes their signal, that are resent by node 1 and 2.

This can be used to concentrate several leaf signal into just one branch, for example, several nodes sending the same signal (button touched, for ex.) and the intermediary signal processor repackaging the signal as emit_signal("button_touched", node_id). I use this specially for UI, with lots of buttons where the only thing that changes is the field of the data record they represent.
But as p7f said, there are lots of ways.

Thank you for your reply, since I am new to Godot, your input is a bit hard for me to understand, but I am sure if I am getting better and more proficient this could be very valuable.

Idleman | 2020-07-09 06:20