Автозагрузки по сравнению с обычными узлами

Godot предлагает возможность автоматической загрузки узлов в корневом каталоге вашего проекта, позволяя вам получить к ним глобальный доступ, который может выполнять роль Singleton: Синглтоны (Автозагрузка). Эти автоматически загружаемые ноды не освобождаются при смене сцены из кода SceneTree.change_scene.

В этом руководстве вы узнаете, когда использовать функцию автозагрузки, и какие приемы можно использовать, чтобы избежать её.

The cutting audio issue

Другие движки могут стимулировать использование создания классов менеджера, синглтонов, которые организуют множество функциональных возможностей в глобально доступный объект. Godot предлагает множество способов избежать глобального состояния благодаря дереву узлов и сигналам.

Например, предположим, что мы создаём платформер и хотим собирать монеты, которые воспроизводят звуковой эффект. Для этого есть узел AudioStreamPlayer. Но если мы вызываем AudioStreamPlayer, когда он уже воспроизводит звук, новый звук прерывает первый.

Решение состоит в том, чтобы закодировать глобальный автоматически загружаемый класс звукового менеджера. Он генерирует пул узлов AudioStreamPlayer, которые циклически повторяются при поступлении каждого нового запроса на звуковые эффекты. Скажем, мы назовём этот класс Sound, вы можете использовать его из любого места в своем проекте, вызвав Sound.play("coin_pickup.ogg"). Это решает проблему в краткосрочной перспективе, но вызывает больше проблем:

  1. Глобальное состояние: теперь один объект отвечает за данные всех объектов. Если в классе Sound есть ошибки или отсутствует AudioStreamPlayer, то все вызывающие его узлы могут сломаться.

  2. Глобальный доступ: теперь, когда любой объект может вызвать Sound.play(sound_path) откуда угодно, более нет простого способа найти источник ошибки.

  3. Глобальное распределение ресурсов: с пулом узлов AudioStreamPlayer, хранящихся с самого начала, вы можете либо иметь слишком мало и сталкиваются с ошибками, или слишком много и использовать больше памяти, чем вам нужно.

Примечание

Что касается глобального доступа, то проблема в том, что любой код где угодно может передать неверные данные в автозагрузку Sound в нашем примере. В результате, домен, который нужно исследовать, чтобы исправить ошибку, охватывает весь проект.

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

Сравните это с тем, что каждая сцена содержит столько узлов AudioStreamPlayer, сколько нужно внутри себя, и все эти проблемы исчезнут:

  1. Каждая сцена управляет собственной информацией о состоянии. Если есть проблема с данными, то она будет вызывать проблемы только в этой одной сцене.

  2. Каждая сцена получает доступ только к своим узлам. Теперь, если есть ошибка, легко найти, какой из узлов виноват.

  3. Каждая сцена выделяет именно то количество ресурсов, которое ей необходимо.

Управление общей функциональностью или данными

Другой причиной использования Autoload может быть то, что вы хотите повторно использовать один и тот же метод или данные во многих сценах.

В случае с функциями можно создать новый тип Node, который обеспечивает эту возможность для отдельной сцены, используя ключевое слово class_name в GDScript.

Когда дело доходит до данных, вы можете:

  1. Создайте новый тип Resource для совместного использования данных.

  2. Храните данные в объекте, к которому имеет доступ каждый узел, например, используя свойство owner для доступа к корневому узлу сцены.

Когда вы должны использовать Autoload (автозагрузку)

В некоторых случаях автоматически загружаемые узлы могут упростить ваш код:

  • Статические данные: если вам нужны данные, которые являются эксклюзивными для одного класса, как база данных, то автозагрузка может быть хорошим инструментом. В Godot нет скриптового API для создания и управления статическими данными в противном случае.

  • Статические функции: создание библиотеки функций, которые возвращают только значения.

  • Системы с широким охватом: если синглтон управляет своей собственной информацией и не вторгается в данные других объектов, то это отличный способ создать системы, которые обрабатывают задачи с широким охватом. Например, квест или диалоговая система.

До Godot 3.1 другое использование было просто для удобства: автозагрузка имеет глобальную переменную для своего имени, созданную в GDScript, что позволяет вам вызывать их из любого файла скрипта в вашем проекте. Но теперь вы можете использовать ключевое слово class_name вместо автозаполнения для типа во всём вашем проекте.

Примечание

Автозагрузка - это не совсем Синглтон. Ничто не мешает вам создавать копии автоматически загружаемого узла. Это всего лишь инструмент, который автоматически загружает узел как дочерний по отношению к корню вашего дерева сцены, независимо от структуры узлов вашей игры или от того, какую сцену вы запускаете, например нажав F6.

В результате вы можете получить автоматически загружаемый узел, например, автозагрузку под названием Sound, вызвав get_node("/root/Sound").