Autoloads im Vergleich zu reguläre Nodes

Godot offers a feature to automatically load nodes at the root of your project, allowing you to access them globally, that can fulfill the role of a Singleton: Singletons (Entwurfsmuster) - AutoLoad. These auto-loaded nodes are not freed when you change the scene from code with SceneTree.change_scene.

In this guide, you will learn when to use the Autoload feature, and techniques you can use to avoid it.

The cutting audio issue

Other engines can encourage the use of creating manager classes, singletons that organize a lot of functionality into a globally accessible object. Godot offers many ways to avoid global state thanks to the node tree and signals.

For example, let's say we are building a platformer and want to collect coins that play a sound effect. There's a node for that: the AudioStreamPlayer. But if we call the AudioStreamPlayer while it is already playing a sound, the new sound interrupts the first.

A solution is to code a global, auto-loaded sound manager class. It generates a pool of AudioStreamPlayer nodes that cycle through as each new request for sound effects comes in. Say we call that class Sound, you can use it from anywhere in your project by calling Sound.play("coin_pickup.ogg"). This solves the problem in the short term but causes more problems:

  1. Global state: one object is now responsible for all objects' data. If the Sound class has errors or doesn't have an AudioStreamPlayer available, all the nodes calling it can break.
  2. Global access: now that any object can call Sound.play(sound_path) from anywhere, there's no longer an easy way to find the source of a bug.
  3. Global resource allocation: with a pool of AudioStreamPlayer nodes stored from the start, you can either have too few and face bugs, or too many and use more memory than you need.

Bemerkung

About global access, the problem is that Any code anywhere could pass wrong data to the Sound autoload in our example. As a result, the domain to explore to fix the bug spans the entire project.

Wenn Sie Code in einer Szene behalten, sind möglicherweise nur ein oder zwei Skripte an der Audioausgabe beteiligt.

Vergleichen Sie dies damit, dass jede Szene so viele AudioStreamPlayer-Nodes enthält wie sie selbst benötigt und all diese Probleme verschwinden:

  1. Jede Szene verwaltet ihre eigenen Statusinformationen. Wenn es ein Problem mit den Daten gibt, tauchen dies nur in dieser einen Szene auf.
  2. Jede Szene greift nur auf ihre eigenen Nodes zu. Wenn es nun einen Fehler gibt, ist es leicht diesen fehlerhaften Node zu finden.
  3. Jede Szene weist genau die Menge an Ressourcen zu, die sie benötigt.

Gemeinsame Funktionen oder Daten verwalten

Ein weiterer Grund für die Verwendung eines Autoloads kann sein, dass Sie dieselbe Methode oder dieselben Daten für viele Szenen wiederverwenden möchten.

In the case of functions, you can create a new type of Node that provides that feature for an individual scene using the class_name keyword in GDScript.

Wenn es um Daten geht, können Sie entweder:

  1. einen neuen Typ Resource erstellen, um die Daten gemeinsam zu nutzen.
  2. die Daten in einem Objekt speichern, auf das jeder Node Zugriff hat, z.B. mithilfe der Eigenschaft owner, um auf den Stamm-Node der Szene zuzugreifen.

Wann Sie ein Autoload verwenden sollten

Automatisch geladene Nodes können Ihren Code in einigen Fällen vereinfachen:

  • Static Data: if you need data that is exclusive to one class, like a database, then an autoload can be a good tool. There is no scripting API in Godot to create and manage static data otherwise.
  • Static functions: creating a library of functions that only return values.
  • Systems with a wide scope: If the singleton is managing its own information and not invading the data of other objects, then it's a great way to create systems that handle broad-scoped tasks. For example, a quest or a dialogue system.

Until Godot 3.1, another use was just for convenience: autoloads have a global variable for their name generated in GDScript, allowing you to call them from any script file in your project. But now, you can use the class_name keyword instead to get auto-completion for a type in your entire project.

Bemerkung

Autoload is not exactly a Singleton. Nothing prevents you from instantiating copies of an auto-loaded node. It is only a tool that makes a node load automatically as a child of the root of your scene tree, regardless of your game's node structure or which scene you run, e.g. by pressing F6 key.

As a result, you can get the auto-loaded node, for example an autoload called Sound, by calling get_node("/root/Sound").