Random beginner-question #8: Get a signal from another scene

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

Hi everyone,

up until now, getting a signal from another scene is a pretty straight forward thing to do:

$"../SceneName".connect("signal_name", self, "signal_name_received")

However, for some reason I don’t succeed in getting a signal from another scene that itself is within another scene. (Error: get_node: Node not found: …/SceneName.)
I tried the path as well:

$"res://scenes/SceneName.tscn".connect("signal_name", self, "signal_name_received")

But nothing works.

What am I doing wrong? How can I set up the path to the signal-emitting scene?
Any suggestions?

:bust_in_silhouette: Reply From: stormreaver

You need to connect instances of the scene, not the scene file itself:

var scene = load(“res://scenes/SceneName.tscn”).instance()
scene.connect(“signal_name”, self, “signal_name_received”)

Preloads work, too (I’m assuming you already know how to arrange preloads):

var Scene = preload(“res://scenes/SceneName.tscn”)
var scene = Scene.instance()
scene.connect(“signal_name”, self, “signal_name_received”)

Putting this in my code:

var scene = load("res://scenes/SceneName.tscn").instance()
scene.connect("signalname", self, "signalname_received")

gives me the message: Unexpected token: Identifier:scene
(I’m really still an absolute beginner, so such things happen to me all the time and I have no idea what the problem could be… probably just a tiny little thing.)

So I instance the scene I want my signal receive from on top of the script and can then set up an according function. That makes sense. But where is the big difference between this and (theoretically) putting “res://scenes/SceneName.tscn” directly into the $-line?

I have never arranged a preload yet - you’re giving me too much credit here ; )
But what would be the dis/advantages of instancing and preloading?

Thanks for your help!

EDIT:

I found something:

var Scene = preload("res://scenes/SceneName.tscn")

needs to be on top of the script.

var scene = Scene.instance()
scene.connect("signalname", self, "signalname_received")

then inside the function.
Do I get this right?

pferft | 2020-08-19 14:09

Looks good to me. Make sure to node.add_child(scene) at some point so the scene is added to the scene tree, if you want it to be visible (or other things, nodes usually need to be added to the tree to be ‘active’)

DDoop | 2020-08-19 19:43

Oh, that’s interesting! So it would work as well without adding as child but… well, but wouldn’t adding a child change my tree?

(Just to be sure: in node.add_child(scene), “scene” is the var scene, yes?
And you say to do this “at some point”. Does it matter where? On top of the script maybe?)

pferft | 2020-08-20 07:52

Yes, “scene” is the var scene. It’s most typical to add the scene to the parent node at the time it is instanced:

var scene = load("res://scenes/SceneName.tscn").instance()

scene.connect("signalname", self, "signalname_received")
add_child(scene)

stormreaver | 2020-08-20 10:55

Thank you all, learning a lot here.

Does add_child mean that a child would be added to the tree-structure at some point? But wouldn’t that be a possible corruption of references?

pferft | 2020-08-20 11:06

The child scene is added to the parent at that moment. You will have to read up on how Godot manages nodes, as it is already explained at length elsewhere. But the short answer is, “not if you understand how Godot manages memory.”

stormreaver | 2020-08-20 11:17

“at that moment”, so it’s not permanent, and that makes sense then! Thank you!
You are right, I realise I didn’t grasp Nodes completely yet…

pferft | 2020-08-20 11:34

How to Hook Into Object Destruction During SceneTree's change_scene() or quit() - Archive - Godot Forum
This question may help clear some things up, but the docs will probably be more useful.

DDoop | 2020-08-20 16:37

Very helpful indeed, thank you!

pferft | 2020-08-24 08:51

Such paths can get quite long. And rearranging/adding/removing Nodes would disconnect everything affected…
But there is the extremely useful “find_node”:

var some-name = get_tree().get_root().find_node(“SpriteButtonBase”)
some-name.connect(“that_button_was_just_released”, self, “that_button_was_just_released_received”)

This should always work, no matter if the tree is being changed etc.

pferft | 2020-08-26 11:42

You can also use export variables for NodePaths that change during development. The editor will let you pick any node from the scene tree while editing in the object inspector.
export (NodePath) var TargetPath

DDoop | 2020-08-26 15:23