Changer de scène manuellement

Parfois, cela aide d'avoir plus de contrôle sur la façon dont on échange les scènes. Comme mentionné ci-dessus, les nœuds enfants d'un Viewport seront rendus dans l'image qu'il génère. Cela est vrai même pour les nœuds en dehors de la scène "actuelle". Les Autoloads entrent dans cette catégorie, mais il en va de même pour des scènes que l'on instance et ajoute à l'arbre de scène lors de l'exécution :

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

func _add_a_scene_manually():
    # This is like autoloading the scene, only
    # it happens after already loading the main scene.
    get_tree().get_root().add_child(simultaneous_scene)
public PackedScene simultaneousScene;

public MyClass()
{
    simultaneousScene = (PackedScene)ResourceLoader.Load("res://levels/level2.tscn").instance();
}

public void _AddASceneManually()
{
    // This is like autoloading the scene, only
    // it happens after already loading the main scene.
    GetTree().GetRoot().AddChild(simultaneousScene);
}

Pour compléter le cycle et échanger la nouvelle scène avec l'ancienne, les développeurs ont un choix à faire. Il existe de nombreuses stratégies pour retirer une scène de la vue du Viewport. Les compromis consistent à équilibrer la vitesse de fonctionnement et la consommation de mémoire ainsi qu'à équilibrer l'accès aux données et leur intégrité.

  1. Nous pouvons supprimer la scène existante. SceneTree.change_scene() et SceneTree.change_scene_to() supprimeront la scène actuelle immédiatement. Les développeurs peuvent également supprimer la scène principale. En supposant que le nom du nœud racine est "Main", on pourrait faire get_node("/root/Main").free() pour supprimer la scène entière.

    • Décharger la mémoire.

      • Avantage : La RAM ne traîne plus de poids mort.
      • Inconvénient : Le retour à cette scène est maintenant plus coûteux car il faut la recharger en mémoire (cela prend du temps ET de la mémoire). Ce n'est pas un problème si retourner rapidement n'est pas nécessaire.
      • Inconvénient : Ne plus avoir accès aux données de cette scène. Pas de problème si l'utilisation de ces données n'est pas rapidement nécessaire.
      • Note : Il peut être utile de préserver les données d'une scène qui sera bientôt supprimée en rattachant un ou plusieurs de ses nœuds à une autre scène, ou même directement au SceneTree.
    • Arrêts de traitement.

      • Avantage : Pas de nœuds signifie pas de processus, de processus physique ou de traitement des entrées. Le CPU est disponible pour travailler sur le contenu de la nouvelle scène.
      • Inconvénient : le traitement et la gestion des entrées de ces nœuds ne fonctionnent plus. Pas de problème si l'utilisation des données mises à jour n'est pas nécessaire.
  2. Nous pouvons masquer la scène existante. En modifiant la visibilité ou la détection de collision des nœuds, nous pouvons masquer entièrement le sous-arbre de nœuds du point de vue du joueur.

    • La mémoire existe toujours.

      • Avantage : On peut toujours accéder aux données en cas de besoin.
      • Avantage : Il n'est pas nécessaire de déplacer des nœuds pour enregistrer les données.
      • Inconvénient : de plus en plus de données sont conservées en mémoire, ce qui va devenir un problème sur les plateformes sensibles à la mémoire comme le web ou le mobile.
    • Le traitement se poursuit.

      • Avantage : Les données continuent de recevoir des mises à jour de traitement, de sorte que la scène gardera à jour toutes les données qu'elle contient qui dépendent des données du temps delta ou d'image(frame).
      • Avantages : Les nœuds sont toujours membres des groupes (puisque les groupes appartiennent au SceneTree).
      • Inconvénient : l'attention du CPU est maintenant divisée entre les deux scènes. Une charge trop importante pourrait entraîner une faible fréquence d'images par seconde. Il faut donc tester les performances au fur et à mesure pour s'assurer que la plate-forme cible peut supporter la charge qu'on lui impose.
  3. Nous pouvons supprimer la scène existante de l'arbre Assignez une variable au nœud racine de la scène existante. Utilisez ensuite Node.remove_child(Node) pour détacher la scène entière de l'arbre.

    • La mémoire existe toujours (avantages/inconvénients similaires au masquage).
    • Le traitement s'arrête (avantages/inconvénients similaires à la suppression complète).
    • Avantage : Cette variante de "masquage" est beaucoup plus facile pour afficher/masquer. Plutôt que de garder potentiellement la trace de plusieurs modifications apportées à la scène, il suffit d'appeler une méthode de la paire de méthodes add/remove_child. Cela revient à désactiver les objets de jeu dans d'autres moteurs.
    • Inconvénient : Contrairement au masquage de la vue uniquement, les données contenues dans la scène deviendront obsolètes si elles dépendent du temps delta, des entrées, des groupes ou d'autres données dérivées de l'accès à SceneTree.

Il y a aussi des cas où l'on peut souhaiter avoir plusieurs scènes présentes en même temps. Peut-être que l'on ajoute son propre singleton au moment de l'exécution ou préserve les données d'une scène entre les changements de scène (en ajoutant la scène au nœud racine).

get_tree().get_root().add_child(scene)
GetTree().GetRoot().AddChild(scene);

Peut-être souhaitent-ils plutôt afficher plusieurs scènes en même temps en utilisant un ViewportContainers. Ceci est optimal dans les cas où l'intention est de rendre un contenu différent dans différentes parties de l'écran. Les Minimaps et le multijoueur en écran partagé sont de bons exemples.

Chaque option aura des cas où elle est la plus appropriée, il faut donc examiner les effets de chacune d'entre elles et déterminer quelle voie correspond le mieux à une situation particulière.