How to connect to a signal when the node is instanced in code and does not know its parentage

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

Hello,
Pretend your scene is like this:

->Game Scene
    -> child1
    -> child2
        -> child21

Inside child21 on being killed a random pickup - object.instance() - is instanced in its place and then frees itself.

When this new instance dies you give the player some health via emitting a signal.

But when the new instance is created, it or child21 that created it has no idea about it’s parentage. So how can a parent object, e.g. ‘Game Scene’ connect to this signal when I’m trying to use signals to avoid knowing about parents, i.e. I want to emit the signal for this very purpose.

Hard-coding a parent or path inside the child21 instance() seems completely counter-intuitive, such as newobject.connect(“pickup”, get_tree().get_root(),“_on_pickup”)

The only way round this that I can see is I have to hold references to certain nodes and inject them into all instance objects or only allow nodes that I want to use as observers to create new instances…

:bust_in_silhouette: Reply From: rustyStriker

you pretty much got it right…

new_object.connect("signal",object,"function")

the object is the one “holding” and “executing” the function, if you dont want to do it that way you can create a function which accepts an object of type T and connect it there

func connect_my_signal_to_your_function_please(new_object : T):
     new_object.connect("signal",self,"function")

thanks, but that’s not what I mean. I use signals everywhere and know how to connect.

It’s just these are new instances created somewhere in the scene tree by a node somewhere else in the scene, so knows absolutely nothing about the parents and the game scene top level parent knows nothing about them either. In fact, the majority of the scene tree is created dynamically so there is no pre-existing structure to some degree.

So ‘object’ in my case I want to be my ‘game scene’. But ‘game scene’ does not instance the node. As I said, changing ‘object’ to get_tree().get_root() seems like a bad thing because the whole point of this is for the children to know nothing about the parent.

chucklepie | 2020-12-06 17:18

:bust_in_silhouette: Reply From: chucklepie

Unless what I want to achieve is bad design, i.e. wanting some parent node to receive a signal when the child is unaware of its existence, I had to do this:

  1. In my ‘game scene’ call a singleton Global method called ‘register_game_scene’
  2. When a new instance creates this another new instance that is a pickup I do this:

new_pickup.connect(“pickup”, Globals.get_game(),“_on_pickup”)

Seems wrong to me.

The whole point of having scenes is to be able to test them in isolation, i.e. the signal is emitted and if the parent is not there then nothing bad happens, here I’ve got to rely on a singleton global which is no better than calling ‘get_parent’ really…

I have a similar problem (an instanced enemy dies inside a child Level of the game, and am trying to update the Score in the GUI that exists outside the Level)

I keep getting basically the same answers, which makes the assumption that you manually are instancing in the scene.

Is this still the solution you settled on?

The only other possibility I came up with, is basically signal chaining up the tree, which seems even worse.

anothervenue | 2020-12-17 18:14