Узлы и экземпляры сцены
В этом руководстве объясняется, как получать узлы, создавать узлы, добавлять их в качестве дочерних элементов и создавать сцены из кода.
См. также
Ознакомьтесь с руководством Создание экземпляров, чтобы узнать о подходе Godot к созданию копий сцен.
Получение узлов
Ссылку на узел можно получить, вызвав метод Node.get_node(). Для этого дочерний узел должен присутствовать в дереве сцены. Получение ссылки в функции _ready() родительского узла гарантирует это.
Например, если у вас есть такое дерево сцены, и вы хотите получить ссылку на узлы Sprite2D и Camera2D, чтобы получить к ним доступ в вашем скрипте.
Для этого вы можете использовать следующий код.
var sprite2d
var camera2d
func _ready():
sprite2d = get_node("Sprite2D")
camera2d = get_node("Camera2D")
private Sprite2D _sprite2D;
private Camera2D _camera2D;
public override void _Ready()
{
base._Ready();
_sprite2D = GetNode<Sprite2D>("Sprite2D");
_camera2D = GetNode<Camera2D>("Camera2D");
}
Обратите внимание, что узлы определяются по имени, а не по типу. Выше "Sprite2D" и "Camera2D" — это имена узлов в сцене.
Если вы переименуете узел Sprite2D в Skin в доке сцены, вам придется изменить строку, которая получает узел, на get_node("Skin") в скрипте.
Пути узлов
При получении ссылки на узел вы не ограничены получением непосредственно дочернего элемента. Функция get_node() поддерживает пути, что немного похоже на работу с файловым браузером. Для разделения узлов добавьте косую черту.
Возьмем следующий пример сцены со скриптом, прикрепленным к узлу UserInterface.
Чтобы получить узел AnimationPlayer, используйте следующий код.
var animation_player
func _ready():
animation_player = get_node("ShieldBar/AnimationPlayer")
private AnimationPlayer _animationPlayer;
public override void _Ready()
{
base._Ready();
_animationPlayer = GetNode<AnimationPlayer>("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.
private Sprite2D _sprite2D;
public override void _Ready()
{
base._Ready();
_sprite2D = new Sprite2D(); // Create a new Sprite2D.
AddChild(_sprite2D); // Add it as a child of this node.
}
Чтобы удалить узел и освободить его из памяти, можно вызвать его метод queue_free(). Это добавит узел в очередь на удаление в конце текущего кадра после завершения его обработки. В этот момент движок удаляет узел из сцены и освобождает объект в памяти.
sprite2d.queue_free()
_sprite2D.QueueFree();
Перед вызовом sprite2d.queue_free() дерево удаленной сцены выглядит следующим образом.
После того, как движок освободил узел, удаленное дерево сцены больше не отображает спрайт.
Вы также можете вызвать free(), чтобы немедленно уничтожить узел. Делайте это с осторожностью, так как любая ссылка на него мгновенно станет null. Рекомендуем использовать queue_free(), если вы не уверены в своих действиях.
При освобождении узла освобождаются и все его дочерние узлы. Благодаря этому, чтобы удалить всю ветвь дерева сцены, достаточно освободить только самый верхний родительский узел.
Инстанцирование сцен
Сцены — это шаблоны, на основе которых можно создать столько копий, сколько нужно. Эта операция называется инстансингом и выполняется из кода в два этапа:
Загрузка сцены с локального диска.
Создание экземпляра загруженного ресурса PackedScene.
var scene = load("res://my_scene.tscn")
var scene = GD.Load<PackedScene>("res://MyScene.tscn");
Предварительная загрузка сцены может улучшить пользовательский опыт, поскольку операция загрузки происходит при чтении скрипта компилятором, а не во время выполнения. Эта функция доступна только в GDScript.
var scene = preload("res://my_scene.tscn")
На этом этапе scene — это упакованный ресурс сцены, а не узел. Чтобы создать сам узел, необходимо вызвать метод PackedScene.instantiate(). Он возвращает дерево узлов, которое можно использовать как дочерний элемент текущего узла.
var instance = scene.instantiate()
add_child(instance)
var instance = scene.Instantiate();
AddChild(instance);
Преимущество этого двухэтапного процесса в том, что вы можете держать сцену загруженной и создавать новые экземпляры «на лету». Например, чтобы быстро создать несколько экземпляров врагов или пуль.