Handling relative NodePath
s
I end up having to do some clever editing of the path to make it work from the node that actually calls the function to change the scene instance.
You don't need any clever editing. You just need to call it from the other Node
.
Instead of doing this:
var node = get_node(other_node.node_path_variable)
Do this:
var node = other_node.get_node(other_node.node_path_variable)
Making NodePath
s absolute
Is there a way to specify to the editor that I want an absolute path exported and saved, rather then a relative one?
This is a NO.
The editor will always create relative NodePath
s. And we cannot workaround it.
To begin to attempt to workaround it, we need to use a tool
script because we want to set the absolute NodePath
on the editor.
But then it will be running in the editor scene tree, which looks different to the scene tree you get while running the game… So the absolute path of the node on the editor scene tree would not work on the game.
And there is NO way to compute the absolute path it will have when you run the game, because that depends on where you will instantiate the scene that you are editing.
At best we can compute the absolute path if the scene you are editing is the current scene (not instantiated inside another scene), but then the NodePath
would be fragile… As soon as you instantiate the scene inside another, the absolute NodePath
would be wrong.
Relative NodePath
s are the way.
Decoupling scenes
My goal so to simply attach the scene instance from the editor an move without having to worry about which parent each instance is attached to.
The general advice is to not reach outside the scene. In particular do not reach outside with hard coded NodePath
s. If your scene depends on where you instantiate it, then your scene is not properly decoupled.
If you need your scene to communicate with nodes that are outside of it, your first option is to add custom signals, which you can connect outside of the scene. And for any information you cannot pass around with signals, you can have the parent call methods on the scene.
For abstract:
Call down, signal up
See Node communication (the right way).
And yes you can expose NodePath
properties, which you can set outside of the scene. That is, you would be telling the scene where the other nodes are.
Godot should update your NodePath
s when you move the Node
s in the scene tree editor. If you have found situations where it does not, please report them. The only case I'm aware it does not work is when you cut or copy Node
s. I'll guess this is what you have been doing. So try dragging them, or use the Reparent option from the context menu.
Anyway, using NodePath
s only gets you to a loosely coupled scene. So here are a couple other ways to fully decouple your scenes:
Using a signal bus: Autoloads are available everywhere. So you can use them for communication. In the case of a signal bus, you create an autoload where you define signals, so those signals can be connected an emitted from any script in any scene. I have an explanation elsewhere.
Using resource based communications: Everywhere when you preload resources or set resources from the editor you always get the same object. So you can use resources for communication. Give the same resource to multiple nodes, and in the resource define properties that they all can access, and signals that they all can be connected and they all can emit. I have an example elsewhere.