Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Узлы и экземпляры сцены
В этом руководстве объясняется, как получать узлы, создавать узлы, добавлять их в качестве дочерних элементов и создавать сцены из кода.
См. также
Ознакомьтесь с руководством Создание экземпляров, чтобы узнать о подходе 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():
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);
Преимущество этого двухэтапного процесса в том, что вы можете держать сцену загруженной и создавать новые экземпляры «на лету». Например, чтобы быстро создать несколько экземпляров врагов или пуль.