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.
Checking the stable version of the documentation...
Cambiare le scene manualmente
Sometimes it helps to have more control over how you swap scenes around. A Viewport's child nodes will render to the image it generates. This holds true even for nodes outside of the "current" scene. Autoloads fall into this category, and also scenes which you instantiate and add to the tree at runtime:
var simultaneous_scene = preload("res://levels/level2.tscn").instantiate()
func _add_a_scene_manually():
# This is like autoloading the scene, only
# it happens after already loading the main scene.
get_tree().root.add_child(simultaneous_scene)
public Node simultaneousScene;
public MyClass()
{
simultaneousScene = ResourceLoader.Load<PackedScene>("res://levels/level2.tscn").Instantiate();
}
public void _AddASceneManually()
{
// This is like autoloading the scene, only
// it happens after already loading the main scene.
GetTree().Root.AddChild(simultaneousScene);
}
To complete the cycle and swap out the new scene with the old one, you have a choice to make. Many strategies exist for removing a scene from view of the Viewport. The tradeoffs involve balancing operation speed and memory consumption, as well as balancing data access and integrity.
Delete the existing scene. SceneTree.change_scene_to_file() and SceneTree.change_scene_to_packed() will delete the current scene immediately. You can also delete the main scene. Assuming the root node's name is "Main", you could do
get_node("/root/Main").free()to delete the whole scene.Libera la memoria.
Pro: RAM is no longer dragging the dead weight.
Con: Returning to that scene is now more expensive since it must be loaded back into memory again (takes time AND memory). Not a problem if returning soon is unnecessary.
Con: No longer have access to that scene's data. Not a problem if using that data soon is unnecessary.
Note: It can be useful to preserve the data in a soon-to-be-deleted scene by re-attaching one or more of its nodes to a different scene, or even directly to the SceneTree.
L'elaborazione si interrompe.
Pro: No nodes means no processing, physics processing, or input handling. The CPU is available to work on the new scene's contents.
Contro: l'elaborazione e la gestione degli input di quei nodi non funzioneranno più. Non è un problema se usare i dati aggiornati non è necessario.
Nascondi la scena esistente. Cambiando la visibilità o il rilevamento delle collisioni dei nodi, è possibile nascondere l'intero sottoalbero dei nodi dalla prospettiva del giocatore. Usa CanvasItem.hide() per nascondere una scena e CanvasItem.show() per rimostrarla.
La memoria esiste ancora.
Pro: è comunque possibile accedere ai dati se necessario.
Pro: non è necessario spostare altri nodi per salvare i dati.
Contro: vengono memorizzati più dati, il che potrebbe diventare un problema su piattaforme sensibili alla memoria come web o dispositivi mobili.
L'elaborazione continua.
Pro: i dati continuano a ricevere aggiornamenti di elaborazione, quindi la scena manterrà aggiornati tutti i dati al suo interno che dipendono dal tempo delta o dai dati dei frame.
Pro: i nodi sono comunque membri di gruppi (poiché i gruppi appartengono allo SceneTree).
Contro: l'attenzione della CPU è ora divisa tra entrambe le scene. Un carico eccessivo potrebbe ridurre il frame rate. È consigliabile testare le prestazioni durante l'esecuzione per assicurarsi che la piattaforma di destinazione sia in grado di supportare il carico derivante da questo approccio.
Rimuovi la scena esistente dall'albero. Assegna una variabile al nodo radice della scena esistente. Quindi usa Node.remove_child(Node) per staccare l'intera scena dall'albero. Per riattaccarla in seguito, usa Node.add_child(Node).
La memoria esiste ancora (pro/contro simili a nasconderla alla vista).
L'elaborazione si interrompe (pro/contro simili a eliminarla completamente).
Pro: This variation of "hiding" it is much easier to show/hide. Rather than potentially keeping track of multiple changes to the scene, you only need to call the add/remove_child methods. This is similar to disabling game objects in other engines.
Contro: a differenza nasconderlo soltanto dalla vista, i dati contenuti nella scena diventeranno obsoleti se dipendono dal tempo delta, input, gruppi o altri dati derivati dall'accesso allo SceneTree.
Esistono anche casi in cui si potrebbe desiderare di avere più scene presenti allo stesso tempo, ad esempio aggiungendo un singleton personalizzato in fase di esecuzione o preservando i dati di una scena tra i cambiamenti di scena (aggiungendo la scena al nodo radice).
get_tree().root.add_child(scene)
GetTree().Root.AddChild(scene);
Un altro caso potrebbe essere visualizzare più scene alla volta attraverso SubViewportContainers. È ottimale per renderizzare contenuti diversi in diverse parti dello schermo (ad esempio, minimappe, multigiocatore a schermo diviso).
Each option will have cases where it is best appropriate, so you must examine the effects of each approach, and determine what path best fits your unique situation.