Автозагрузки по сравнению с обычными узлами¶
Godot предлагает возможность автоматической загрузки узлов в корневом каталоге вашего проекта, позволяя вам получить к ним глобальный доступ, который может выполнять роль Singleton: Синглтоны (Автозагрузка). Эти автоматически загружаемые ноды не освобождаются при смене сцены из кода SceneTree.change_scene.
В этом руководстве вы узнаете, когда использовать функцию автозагрузки, и какие приемы можно использовать, чтобы избежать её.
Проблема с прерыванием звука¶
Другие движки могут стимулировать использование создания классов менеджера, синглтонов, которые организуют множество функциональных возможностей в глобально доступный объект. Godot предлагает множество способов избежать глобального состояния благодаря дереву узлов и сигналам.
Например, предположим, что мы создаём платформер и хотим собирать монеты, которые воспроизводят звуковой эффект. Для этого есть узел AudioStreamPlayer. Но если мы вызываем AudioStreamPlayer, когда он уже воспроизводит звук, новый звук прерывает первый.
Решение состоит в том, чтобы закодировать глобальный автоматически загружаемый класс звукового менеджера. Он генерирует пул узлов AudioStreamPlayer, которые циклически повторяются при поступлении каждого нового запроса на звуковые эффекты. Скажем, мы назовём этот класс Sound
, вы можете использовать его из любого места в своем проекте, вызвав Sound.play("coin_pickup.ogg")
. Это решает проблему в краткосрочной перспективе, но вызывает больше проблем:
Глобальное состояние: теперь один объект отвечает за данные всех объектов. Если в классе
Sound
есть ошибки или отсутствует AudioStreamPlayer, то все вызывающие его узлы могут сломаться.Глобальный доступ: теперь, когда любой объект может вызвать
Sound.play(sound_path)
откуда угодно, более нет простого способа найти источник ошибки.Глобальное распределение ресурсов: с пулом узлов
AudioStreamPlayer
, хранящихся с самого начала, вы можете либо иметь слишком мало и сталкиваются с ошибками, или слишком много и использовать больше памяти, чем вам нужно.
Примечание
Что касается глобального доступа, то проблема в том, что любой код где угодно может передать неверные данные в автозагрузку Sound
в нашем примере. В результате, домен, который нужно исследовать, чтобы исправить ошибку, охватывает весь проект.
Когда вы храните код внутри сцены, только один или два скрипта могут быть задействованы в аудио.
Сравните это с тем, что каждая сцена содержит столько узлов AudioStreamPlayer
, сколько нужно внутри себя, и все эти проблемы исчезнут:
Каждая сцена управляет собственной информацией о состоянии. Если есть проблема с данными, то она будет вызывать проблемы только в этой одной сцене.
Каждая сцена получает доступ только к своим узлам. Теперь, если есть ошибка, легко найти, какой из узлов виноват.
Каждая сцена выделяет именно то количество ресурсов, которое ей необходимо.
Когда вы должны использовать Autoload (автозагрузку)¶
В некоторых случаях автоматически загружаемые узлы могут упростить ваш код:
Статические данные: если вам нужны данные, которые являются эксклюзивными для одного класса, как база данных, то автозагрузка может быть хорошим инструментом. В Godot нет скриптового API для создания и управления статическими данными в противном случае.
Статические функции: создание библиотеки функций, которые возвращают только значения.
Системы с широким охватом: если синглтон управляет своей собственной информацией и не вторгается в данные других объектов, то это отличный способ создать системы, которые обрабатывают задачи с широким охватом. Например, квест или диалоговая система.
До Godot 3.1 другое использование было просто для удобства: автозагрузка имеет глобальную переменную для своего имени, созданную в GDScript, что позволяет вам вызывать их из любого файла скрипта в вашем проекте. Но теперь вы можете использовать ключевое слово class_name
вместо автозаполнения для типа во всём вашем проекте.
Примечание
Автозагрузка - это не совсем Синглтон. Ничто не мешает вам создавать копии автоматически загружаемого узла. Это всего лишь инструмент, который автоматически загружает узел как дочерний по отношению к корню вашего дерева сцены, независимо от структуры узлов вашей игры или от того, какую сцену вы запускаете, например нажав F6.
В результате вы можете получить автоматически загружаемый узел, например, автозагрузку под названием Sound
, вызвав get_node("/root/Sound")
.