В чем разница между загрузкой сцены с .instance и использованием .new?

Работая в Годо 3.2, у меня есть сцена Player.tscn. В верхней части Player.tscn у меня есть "class_name Player"

Теперь при создании экземпляра Player у меня, насколько я понимаю, есть два варианта:

player = Player.new()

or

player = load("res://Player.tscn").instance() as Player

Мне кажется, лучше всего первая версия ... но это явно не так. Если я использую .new(), он утверждает, что у него нет дочерних элементов, и любые вызовы методов, которые пытаются добраться до его дочерних элементов (например, .get_texture() в Sprite), производят такие вещи, как «Attempt to call function 'get_texture' in base 'null instance' on a null instance», потому что, очевидно, Player не имеет дочерних элементов.

Конечно, по второму способу все работает нормально. Но почему? Почему я не могу просто использовать .new(), если я зарегистрировал его как класс с помощью class_name?


person timdiggerm    schedule 14.04.2020    source источник


Ответы (1)


Я сам новичок в Godot, поэтому могу ошибаться, но я думаю, что это потому, что ключевое слово .new () - это языковая функция для загрузки отдельных классов / узлов,

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

Итак, если ваш плеер - сцена tscn, вы должны сделать что-то вроде:

var player = load("res://etc/Player.tscn").instance()
get_tree().root.add_child(player)
player.global_transform = etc ...

который загрузит корневой узел Player.tscn и всех его дочерних элементов (твердые тела, формы коллайдера и т. д.) в дерево сцены, установит их относительные позиции, соединит скрипты и все, что у вас есть

Или, если ваш Player является классом или GDScript, вы можете сделать

var player = Player.new()
get_tree().root.add_child(player)
player.global_transform = etc ...

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

Как только он находится в дереве сцены и запускается _ready (), вы можете создать и присоединить узлы дочерних компонентов (.new ()> parent.add_child ()> set transform) из самого скрипта

person hardcodeHagrid    schedule 18.04.2020