My question is simple. How to get a reference in code to a node, and not have that reference break if the node is moved in the scene tree, and/or if the node is renamed.
The unique name identifier (%) is not useful. This depends on the node name. Using the scene reference (…/nodex/nodey) is not useful. This depends on the node position in the scene tree.
Is this possible? Does every node (or scene) added to the tree have some unique ID or something I can reference?
Because its tiring to be making a new game which obviously is not finished nor correctly ordered, and have all my code break when I move and/or rename a node.
get the node and store the result in a variable. below is an example where i rename/orphan/re-parent node B. after all that m_b_node == get_node_or_null("/root/Test/A/NewNameForNodeB") still works.
I mostly use groups to grab any particular node. My player character has his own group. My game controller is in the “game” group. Buttons are in multiple groups, by function (mostly assigned based on their name). No matter where I move them, they’re still in their groups.
The simplest way to get nodes no matter where they are or they name is use groups, in the node you want to get the reference use add_to_group("group_name") and in the script you want to get the reference you can use either get_tree().get_nodes_in_group("group_name") (will return an array with all nodes inside this group) or get_tree().get_first_node_in_group("group_name") (if you have only one node in the group you can use this to get the node directly)
I want to have a reference that doesnt break when moving or renaming the referenced node while in editor mode (during design). Not while playing the game.
So if I, while developing and not playing, move a node permanently on the scene tree or rename it. Then, I want this reference to not break and have to update it manually.
@onready var player: Node2D = get_tree().get_first_node_in_group(“player”)
Now, as long as I dont rename the group, all the code that references stuff from that group will not break.
Also, I will probably add a singleton class with all the available group names, so if I decide to rename the group, I only have to change code in 1 place.
This solution also sounds intresting. But how do I use it?
In my case my specific problem is:
I have a Game root scene with a Player scene inside it. The Player scene has a Gun scene inside. The Gun scene emits a signal bulletsChanged(bulletsAmount).
I want the BulletsLabel to listen for the Gun signal.
Here is the BulletsLabel script right now as I have it using groups (this works perfectly). Could I instead reference an exported variable from the Player scene instead? I think that would be a cleaner solution for me.
extends Label
func _ready():
var gun = get_tree().get_first_node_in_group("gun")
gun.bulletsChanged.connect(_gun_bullets_changed)
func _gun_bullets_changed(newBullets):
text = "Balas: " + str(newBullets) + "/10"