Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Utilizzo dello SceneTree

Introduzione

Nei tutorial precedenti, tutto ruotava intorno al concetto dei nodi. Le scene sono raccolte di nodi. Diventano attivi una volta entrati nell'albero di scene.

MainLoop

Il modo in cui Godot funziona internamente è il seguente. Esiste la classe OS, che è l'unica istanza che viene eseguita all'inizio. Successivamente, vengono caricati tutti i driver, i server, i linguaggi di scripting, il sistema di scene, ecc.

Una volta completata l'inizializzazione, è necessario fornire a OS un MainLoop da eseguire. Fino a questo punto, si trattano di operazioni interne (puoi dare un'occhiata al file main/main.cpp nel codice sorgente se sei interessato a vedere come funziona internamente).

Il programma utente, o gioco, inizia nella classe MainLoop. Questa classe ha alcuni metodi, per l'inizializzazione, lo stato di inattività (callback sincronizzato con il frame), lo stato fisso (callback sincronizzato con la fisica) e l'input. Anche in questo caso, si tratta di un livello basso e, quando si sviluppano giochi in Godot, scrivere una propria classe MainLoop raramente ha senso.

SceneTree

Uno dei modi per spiegare come funziona Godot è considerarlo un motore di gioco di alto livello basato su un middleware di basso livello.

Il sistema di scene è il motore di gioco, mentre l'OS e i server sono le API di basso livello.

Il sistema di scene fornisce all'OS il proprio ciclo principale, SceneTree. Questo è istanziato e impostato automaticamente all'eseguzione di una scena, senza dover fare altro.

È importante sapere che questa classe esiste perché ha alcuni utilizzi importanti:

  • It contains the root Viewport, to which a scene is added as a child when it's first opened to become part of the Scene Tree (more on that next).

  • It contains information about the groups and has the means to call all nodes in a group or get a list of them.

  • It contains some global state functionality, such as setting pause mode or quitting the process.

When a node is part of the Scene Tree, the SceneTree singleton can be obtained by calling Node.get_tree().

Viewport radice

La Viewport radice si trova sempre in alto la scena. Da un nodo, è possibile ricavarla in due modi diversi:

get_tree().root # Access via scene main loop.
get_node("/root") # Access via absolute path.

This node contains the main viewport. Anything that is a child of a Viewport is drawn inside of it by default, so it makes sense that the top of all nodes is always a node of this type otherwise nothing would be seen.

While other viewports can be created in the scene (for split-screen effects and such), this one is the only one that is never created by the user. It's created automatically inside SceneTree.

Albero di scene

When a node is connected, directly or indirectly, to the root viewport, it becomes part of the scene tree.

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

../../_images/activescene.webp

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.

Ordine d'albero

Most node operations in Godot, such as drawing 2D, processing, or getting notifications are done in tree order, or top to bottom as seen in the editor (also known as pre-order traversal):

../../_images/toptobottom.webp

For example, the top node in a scene has its _process() function called first, then the node below it has its _process() function called, then the node below that and so on.

An important exception is the _ready() function: each parent node has its _ready() function called only after all its child nodes have their _ready() functions called, so that the parent knows its children are completely ready to be accessed. This is also known as post-order traversal. In the above image, NameLabel would be notified first (but only after its children, if it had any!), followed by Name, etc., and Panel would be notified last.

The order of operations can also be overridden using the process_priority node property. Nodes with a lower number are called first. For example, nodes with the priorities "0, 1, 2, 3" would be called in that order from left to right.

"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 of its descendants.

  3. Every node of the newly added scene will receive the "enter_tree" notification ( _enter_tree() callback in GDScript) in top-to-bottom order (pre-order traversal).

  4. Every node will receive the "ready" notification ( _ready() callback in GDScript) for convenience, once all its children have received the "ready" notification (post-order traversal).

  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 (the exact reverse of top-to-bottom order).

Cambiare la scena attuale

Dopo aver caricato una scena, potresti volerla sostituire con un'altra. Un modo per farlo è tramite la funzione SceneTree.change_scene_to_file():

func _my_level_was_completed():
    get_tree().change_scene_to_file("res://levels/level2.tscn")

Anziché utilizzare percorsi di file, è anche possibile utilizzare risorse PackedScene già pronte tramite la funzione equivalente SceneTree.change_scene_to_packed(PackedScene scene):

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

func _my_level_was_completed():
    get_tree().change_scene_to_packed(next_scene)

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 threaded (background) loading. This must be done manually using Singleton (Autoload) and Caricamento nello sfondo.