Up to date

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

Utilisation de SceneTree

Introduction

Dans le tutoriel précédent, tout tournait autour du concept des nœuds. Chaque scène est simplement une collection de nœud. Elles deviennent actives une fois entrée dans l'arbre de scène.

MainLoop

La façon dont Godot fonctionne en interne est la suivante : Au départ, la seule instance qui fonctionne est la classe OS, ensuite, tous les pilotes, serveurs, langages de script, système de gestion de scènes ... sont chargés.

Quand l'initialisation est terminée, OS doit être fournie à MainLoop pour fonctionner. Jusqu'à ce point, tout ceci est du fonctionnement interne (vous pouvez consulter le fichier main/main.cpp dans le code source si jamais vous êtes intéressé de voir comment cela fonctionne en interne).

Le programme utilisateur, ou le jeu, démarre dans le MainLoop. Cette classe a quelques méthodes, pour l'initialisation, l'inactivité (rappel synchronisé par trame), fixé (rappel synchronisé par la physique) et les entrées. Encore une fois, ceci est bas niveau et lorsque vous créez des jeux avec Godot, écrire votre propre MainLoop a rarement du sens.

ArbreDesScènes

L'un des manières d'expliquer comment Godot fonctionne est qu'il est un moteur de jeu de haut niveau, construit par-dessus un middleware de bas niveau.

Le système de gestion de scènes est le game engine, tandis que OS et les serveurs sont partis de l'API de bas niveau.

Le système de scène fournit sa propre boucle principale à l'OS, SceneTree. Elle est automatiquement instanciée et configurée lors de l'exécution d'une scène, aucun travail supplémentaire est nécessaire.

Il est important de savoir que cette classe existe car elle a des utilisations importantes :

  • Elle contient le Viewport racine, à laquelle une scène est ajoutée en tant qu'enfant lorsqu'elle est ouverte pour la première fois, afin de faire partie de l'arborescence de scène Scene Tree (plus d'informations là-dessus par la suite).

  • Elle contient des informations sur les groupes et permet d'appeler tous les nœuds d'un groupe ou d'obtenir une liste de ceux-ci.

  • Elle contient certaines fonctionnalités d'état global, comme le réglage du mode pause ou quitter le processus.

Lorsqu'un nœud fait partie de l'arbre des scènes, le singleton SceneTree peut être obtenu en appelant simplement Node.get_tree().

Le viewport racine

Le Viewport racine est toujours en haut de la scène. A partir d'un nœud, il peut être obtenu de deux manières différentes :

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

Ce nœud contient la fenêtre d'affichage principale. Tout ce qui est un enfant d'un Viewport est dessiné à l'intérieur de celui-ci par défaut, il est donc logique que le nœud en amont de tous les autres soit toujours un nœud de ce type, sinon rien ne serait vu.

Alors que d'autres viewports peuvent être créés dans la scène (pour des effets d'écran partagé et autres), celui-ci est le seul qui n'est jamais créé par l'utilisateur. Il est créé automatiquement à l'intérieur de SceneTree.

Scene tree (Arbre de scène)

Lorsqu'un nœud est connecté, directement ou indirectement, au viewport racine, il fait partie de l'arborescence des scènes.

Cela signifie que, comme expliqué dans les tutoriels précédents, il recevra les rappels de _enter_tree() et _ready() (ainsi que _exit_tree()).

../../_images/activescene.webp

Lorsque les nœuds entrent dans l'arbre de scène, ils deviennent actifs. Ils ont accès à tout ce dont ils ont besoin pour fonctionner, obtenir des entrées, afficher des données en 2D et 3D, recevoir et envoyer des notifications, jouer du son, etc. Lorsqu'ils sont retirés de l'arbre de scène, ils perdent cet accès.

Ordre de l'arborescence

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.

"Activation" en entrant dans l'arbre de scène (Scene Tree)

  1. Une scène est chargée à partir du disque ou créée par un script.

  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).

Changement de la scène courante

After a scene is loaded, you may want to change this scene for another one. One way to do this is to use the SceneTree.change_scene_to_file() function:

func _my_level_was_completed():
    get_tree().change_scene_to_file("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_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 Singletons (Autoload) and Chargement en arrière-plan.