Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Autoloads im Vergleich zu regulären Nodes

Godot bietet ein Feature zum automatischen Laden von Nodes im Root Ihres Projekts, das es Ihnen ermöglicht, global auf sie zuzugreifen und das die Rolle eines Singletons : Singletons (AutoLoad) erfüllen kann. Diese automatisch geladenen Nodes werden nicht freigegeben, wenn Sie die Szene über den Code mit SceneTree.change_scene_to_file ändern.

In dieser Anleitung erfahren Sie, wann Sie das Autoload-Feature verwenden sollten und welche Techniken Sie verwenden können, um es zu umgehen.

Das Problem mit abgehackten Sounds

Andere Engines können zur Verwendung von Manager-Klassen zum Erzeugen von Objekten ermutigen: Singletons, die viele Funktionen in einem global zugänglichen Objekt organisieren. Godot bietet dank des Node-Baums und der Signale viele Möglichkeiten, einen globalen Zustand zu vermeiden.

Nehmen wir zum Beispiel an, wir bauen einen Plattformer und möchten Münzen sammeln, wobei ein Soundeffekt abgespielt wird. Dafür gibt es einen Node: den AudioStreamPlayer. Wenn wir jedoch den AudioStreamPlayer aufrufen, während bereits ein Sound abgespielt wird, unterbricht der neue Sound den vorherigen.

Eine Lösung besteht darin, eine globale, automatisch geladene Soundmanager-Klasse zu programmieren. Sie erzeugt einen Pool von AudioStreamPlayer-Nodes, die bei jeder neuen Anfrage für Soundeffekte durchlaufen werden. Sagen wir, wir nennen diese Klasse Sound, dann können Sie sie von überall in Ihrem Projekt benutzen, indem Sie Sound.play("coin_pickup.ogg") aufrufen. Dies löst das Problem kurzfristig, führt aber zu weiteren Problemen:

  1. Globaler Status: Ein Objekt ist jetzt für alle Objektdaten verantwortlich. Wenn die Sound-Klasse Fehler aufweist oder kein AudioStreamPlayer verfügbar ist, können alle aufrufenden Nodes Probleme bekommen.

  2. Globaler Zugriff: Jetzt, da jedes Objekt Sound.play(sound_path) von überall aufrufen kann, gibt es keine einfache Möglichkeit mehr, die Ursache eines Fehlers zu finden.

  3. Globale Ressourcenallokation: Mit einem Pool von AudioStreamPlayer-Nodes, die von Anfang an gespeichert wurden, können Sie entweder zu wenige Nodes haben und damit Bugs erzeugen, oder zu viele und dadurch deutlich mehr Speicher verwenden als benötigt.

Bemerkung

Das Problem beim globalen Zugriff besteht darin, dass jede beliebige Codestelle von irgendwoher falsche Daten an den Sound-Autoload unseres Beispiels übergeben könnte. Infolgedessen erstreckt sich der zu überprüfende Bereich zur Behebung des Bugs über das gesamte Projekt.

Wenn Sie dagegen Code in einer Szene halten, 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, taucht 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 alloziert genau die Menge an Ressourcen, 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.

Im Fall von Funktionen können Sie einen neuen Typ von Node erstellen, der dieses Feature für eine einzelne Szene bereitstellt, indem Sie das Schlüsselwort class_name in GDScript verwenden.

In Bezug auf Daten 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 owner-Property, um auf den Root-Node der Szene zuzugreifen.

Wann Sie ein Autoload verwenden sollten

GDScript unterstützt die Nutzung von static-Funktionen, über static func. Kombiniert mit class_name ermöglicht dies, Bibliotheken von Helferfunktion zu kreieren, ohne diese Funktionen vorher instanziieren zu müssen, um sie aufzurufen. Diese statischen Funktionen können jedoch keine Member-Variablen, nicht-statische Funktionen oder self referenzieren.

Seit Godot 4.1 unterstützt GDScript auch statische Variablen über static var. So können Sie Variablen zwischen den Instanzen einer Klasse teilen ohne ein separates Autoload zu erstellen.

Dennoch können Autoload-Nodes Ihren Code für Systeme mit einem großen Geltungsbereich vereinfachen. Wenn der Autoload seine eigenen Informationen verwaltet und nicht in die Daten anderer Objekte eindringt, dann ist dies eine großartige Möglichkeit, Systeme zu erstellen, die Aufgaben mit breitem Geltungsbereich erledigen. Zum Beispiel eine Suche oder ein Dialogsystem.

Bemerkung

Ein Autoload ist nicht notwendigerweise ein Singleton. Nichts hindert Sie daran, Kopien eines Autoload-Nodes zu instanziieren. Ein Autoload ist nur ein Werkzeug, das einen Node automatisch als Child-Node des Roots Ihres Szenenbaums lädt, unabhängig von der Node-Struktur Ihres Spiels oder der Szene, die Sie ausführen, z.B. durch Drücken der Taste F6.

Als Ergebnis können Sie den Autoload-Node, zum Beispiel einen Autoload namens Sound, durch den Aufruf von get_node("/root/Sound") erhalten.