Szenen-Baum (SceneTree)

Einführung

In vorangegangen Tutorials drehte sich alles um das Konzept der Nodes. Szenen sind Sammlungen von Nodes. Sie werden aktiv sobald sie in den Szenen-Baum (scene tree) eingefügt werden.

MainLoop

Godot arbeitet intern wie folgt. Eine OS-Klasse (OS) ist die einzige Instanz die zu Begin ausgeführt wird. Darauf folgend werden Treiber, Server, Scriptsprachen, Szenen-System etc. geladen.

Sobald die Initialisierung abgeschlossen ist, wird OS ein MainLoop übergeben um ausgeführt zu werden. Bis zu diesem Punkt ist alles interner Ablauf (siehe main/main.cpp im source code falls Interesse besteht die Internen Abläufe nachzuvollziehen).

Die Nutzer-Anwendung, oder das Spiel, startet im MainLoop. Diese Klasse definiert Methoden für die Initialisierung, Idle (Bild-synchrone Rückrufmethode), fixed (Physik-synchrone Rückrufmethode) und Eingabe (input). Dies sind tief gehende Funktionen, welche in der typischen Erstellung eines Spiels nur sehr selten verwendet werden.

Szenen-Baum (SceneTree)

Godot kann so erklärt werden, dass es eine High Level Game Engine über einer Low Level Middleware ist.

Das Szenensystem ist die Game Engine, wohingegen das :ref:`OS <class_OS> und Server zur Low Level API gehören.

Das Szenen-System stellt eine Implemetierung des MainLoops dar (SceneTree) welcher OS so übergeben wird. Dies geschieht standardmäßig automatisch sobald eine Szene ausgeführt wird und erfordert kein manuelles Eingreifen.

Es ist wichtig zu wissen, dass es diese Klasse gibt, weil sie einige wichtige Verwendungszwecke hat:

  • Es beinhaltet die Wurzel Viewport, zu welcher eine Szene hinzugefügt wird, als Kind, welches beim ersten Öffnen Teil des Szenen-Baums (Scene Tree) wird.
  • Es enthält Informationen zu Gruppen und hat Möglichkeiten Node-Methoden einer Gruppe aufzurufen oder eine Liste dieser zu erstellen.
  • Es beinhaltet einige Funktionalität zum Globalen Zustand, wie dem Pausieren oder Beenden des Prozesses.

Wenn ein Node teil des Szenen-Baums (Scene Tree) ist, kann auf den Szenen-Baum (SceneTree) als Singleton über :ref:`Node.get_tree() <class_Node_method_get_tree>`zugegriffen werden.

Wurzel Fenster (Viewport)

Das Wurzel-Fenster (Viewport) ist immer am oberen Ende der Szene. Durch einen Node kann über folgende Wege auf es zugegriffen werden:

get_tree().get_root() # Access via scene main loop.
get_node("/root") # Access via absolute path.
GetTree().GetRoot(); // Access via scene main loop.
GetNode("/root"); // Access via absolute path.

Dieser Node enthält das Haupt-Fenster (Viewport - Viewport). Alles was diesem untergeordnet ist wird standardmäßig dargestellt, so macht es Sinn das die Wurzel aller Nodes immer ein Node dieses Typs ist, andererseits ist nichts sichtbar.

Wärend andere Fenster (Viewport) in der Szene erstellt werden können (für Split-screens z.B.), ist dieses das einzige das nicht vom Nutzer erstellt wird. Es wird automatisch durch den Szenen-Baum (SceneTree) bereitgestellt.

Szenen-Baum (SceneTree)

Wenn ein Node eingebunden wird, direkt oder indirekt, in das Wurzel-Fenster (Viewport) wird es Teil des Szenen-Baums (SceneTree).

This means that as explained in previous tutorials, it will get the _enter_tree() and _ready() callbacks (as well as _exit_tree()).

../../_images/activescene.png

When nodes enter the Scene Tree, they become active. They get access to everything they need to process, get input, display 2D and 3D visuals, receive and send notifications, play sounds, etc. When they are removed from the scene tree, they lose these abilities.

Tree order

Most node operations in Godot, such as drawing 2D, processing, or getting notifications are done in tree order. This means that parents and siblings with a lower rank in the tree order will get notified before the current node.

../../_images/toptobottom.png

„Becoming active“ by entering the Scene Tree

  1. A scene is loaded from disk or created by scripting.
  2. The root node of that scene (only one root, remember?) is added as either a child of the „root“ Viewport (from SceneTree), or to any child or grandchild of it.
  3. Every node of the newly added scene, will receive the „enter_tree“ notification ( _enter_tree() callback in GDScript) in top-to-bottom order.
  4. An extra notification, „ready“ ( _ready() callback in GDScript) is provided for convenience, when a node and all its children are inside the active scene.
  5. When a scene (or part of it) is removed, they receive the „exit scene“ notification ( _exit_tree() callback in GDScript) in bottom-to-top order

Changing current scene

After a scene is loaded, it is often desired to change this scene for another one. The simple way to do this is to use the SceneTree.change_scene() function:

func _my_level_was_completed():
    get_tree().change_scene("res://levels/level2.tscn")
public void _MyLevelWasCompleted()
{
    GetTree().ChangeScene("res://levels/level2.tscn");
}

Rather than using file paths, one can also use ready-made PackedScene resources using the equivalent function SceneTree.change_scene_to(PackedScene scene):

var next_scene = preload("res://levels/level2.tscn")

func _my_level_was_completed():
    get_tree().change_scene_to(next_scene)
public void _MyLevelWasCompleted()
{
    var nextScene = (PackedScene)ResourceLoader.Load("res://levels/level2.tscn");
    GetTree().ChangeSceneTo(nextScene);
}

These are quick and useful ways to switch scenes but have the drawback that the game will stall until the new scene is loaded and running. At some point in the development of your game, it may be preferable to create proper loading screens with progress bar, animated indicators or thread (background) loading. This must be done manually using autoloads (see next chapter) and Background loading.