Узлы и экземпляры сцены

В этом руководстве объясняется, как получать узлы, создавать узлы, добавлять их в качестве дочерних элементов и создавать сцены из кода.

См. также

Ознакомьтесь с руководством Создание экземпляров, чтобы узнать о подходе Godot к созданию копий сцен.

Получение узлов

Ссылку на узел можно получить, вызвав метод Node.get_node(). Для этого дочерний узел должен присутствовать в дереве сцены. Получение ссылки в функции _ready() родительского узла гарантирует это.

Например, если у вас есть такое дерево сцены, и вы хотите получить ссылку на узлы Sprite2D и Camera2D, чтобы получить к ним доступ в вашем скрипте.

../../_images/nodes_and_scene_instances_player_scene_example.webp

Для этого вы можете использовать следующий код.

var sprite2d
var camera2d

func _ready():
    sprite2d = get_node("Sprite2D")
    camera2d = get_node("Camera2D")

Обратите внимание, что узлы определяются по имени, а не по типу. Выше "Sprite2D" и "Camera2D" — это имена узлов в сцене.

../../_images/nodes_and_scene_instances_sprite_node.webp

Если вы переименуете узел Sprite2D в Skin в доке сцены, вам придется изменить строку, которая получает узел, на get_node("Skin") в скрипте.

../../_images/nodes_and_scene_instances_sprite_node_renamed.webp

Пути узлов

При получении ссылки на узел вы не ограничены получением непосредственно дочернего элемента. Функция get_node() поддерживает пути, что немного похоже на работу с файловым браузером. Для разделения узлов добавьте косую черту.

Возьмем следующий пример сцены со скриптом, прикрепленным к узлу UserInterface.

../../_images/nodes_and_scene_instances_ui_scene_example.webp

Чтобы получить узел AnimationPlayer, используйте следующий код.

var animation_player

func _ready():
    animation_player = get_node("ShieldBar/AnimationPlayer")

Примечание

Как и в случае с путями к файлам, для получения родительского узла можно использовать "..". Рекомендуется избегать этого, но при этом не нарушать инкапсуляцию. Путь также можно начать с косой черты, чтобы сделать его абсолютным. В этом случае самым верхним узлом будет "/root" — предопределённая корневая область просмотра приложения.

Синтаксический сахар

Для сокращения кода в GDScript можно использовать два способа. Во-первых, добавление аннотации @onready перед переменной-членом приводит к её инициализации непосредственно перед функцией обратного вызова _ready().

@onready var sprite2d = get_node("Sprite2D")

Существует также сокращённая запись для get_node(): знак доллара ($). Он помещается перед именем или путём к узлу, который нужно получить.

@onready var sprite2d = $Sprite2D
@onready var animation_player = $ShieldBar/AnimationPlayer

Создание узлов

Чтобы создать узел из кода, вызовите его метод new(), как для любого другого типа данных, основанного на классе.

Вы можете сохранить ссылку на вновь созданный узел в переменной и вызвать add_child(), чтобы добавить его в качестве дочернего узла того узла, к которому вы прикрепили скрипт.

var sprite2d

func _ready():
    var sprite2d = Sprite2D.new() # Create a new Sprite2D.
    add_child(sprite2d) # Add it as a child of this node.

Чтобы удалить узел и освободить его из памяти, можно вызвать его метод queue_free(). Это добавит узел в очередь на удаление в конце текущего кадра после завершения его обработки. В этот момент движок удаляет узел из сцены и освобождает объект в памяти.

sprite2d.queue_free()

Перед вызовом sprite2d.queue_free() дерево удаленной сцены выглядит следующим образом.

../../_images/nodes_and_scene_instances_remote_tree_with_sprite.webp

После того, как движок освободил узел, удаленное дерево сцены больше не отображает спрайт.

../../_images/nodes_and_scene_instances_remote_tree_no_sprite.webp

Вы также можете вызвать free(), чтобы немедленно уничтожить узел. Делайте это с осторожностью, так как любая ссылка на него мгновенно станет null. Рекомендуем использовать queue_free(), если вы не уверены в своих действиях.

При освобождении узла освобождаются и все его дочерние узлы. Благодаря этому, чтобы удалить всю ветвь дерева сцены, достаточно освободить только самый верхний родительский узел.

Инстанцирование сцен

Сцены — это шаблоны, на основе которых можно создать столько копий, сколько нужно. Эта операция называется инстансингом и выполняется из кода в два этапа:

  1. Загрузка сцены с локального диска.

  2. Создание экземпляра загруженного ресурса PackedScene.

var scene = load("res://my_scene.tscn")

Предварительная загрузка сцены может улучшить пользовательский опыт, поскольку операция загрузки происходит при чтении скрипта компилятором, а не во время выполнения. Эта функция доступна только в GDScript.

var scene = preload("res://my_scene.tscn")

На этом этапе scene — это упакованный ресурс сцены, а не узел. Чтобы создать сам узел, необходимо вызвать метод PackedScene.instantiate(). Он возвращает дерево узлов, которое можно использовать как дочерний элемент текущего узла.

var instance = scene.instantiate()
add_child(instance)

Преимущество этого двухэтапного процесса в том, что вы можете держать сцену загруженной и создавать новые экземпляры «на лету». Например, чтобы быстро создать несколько экземпляров врагов или пуль.