Node References and the Scene Tree
A script attached to one node very often needs to reach other nodes nearby in the scene tree, to read their state or call their methods.
extends CharacterBody2D
@onready var sprite = $Sprite2D
@onready var collision_shape = $CollisionShape2D
func _ready():
sprite.modulate = Color.RED
$Sprite2D is shorthand for get_node("Sprite2D"), fetching a direct child node by name. @onready delays that lookup until the node has actually entered the scene tree, if you tried to grab $Sprite2D immediately when the script's variables are first declared, the child node might not exist yet.
Relative and absolute paths
var sibling = get_node("../Enemy") # relative: up one level, then into Enemy
var anywhere = get_node("/root/Game/UI") # absolute: from the very root of the tree
Relative paths (".." for parent, a name for a child) are more portable, since they don't break if the whole scene gets moved somewhere else in a larger tree, absolute paths are more explicit but brittle if the tree's structure changes.
Groups
For finding many unrelated nodes at once, node groups are usually cleaner than manual tree-walking:
# In the editor, add each enemy node to a group called "enemies"
for enemy in get_tree().get_nodes_in_group("enemies"):
enemy.take_damage(10)
Groups decouple "find all the enemies" from the tree's exact shape entirely, new enemies just need to join the group, no code elsewhere needs to change.