PackedScene Best for Remembering a Scene's State?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By uheartbeast
:warning: Old Version Published before Godot 3 was released.

I want to change scenes but remember the state of the previous scene, like in Pokemon where you enter the battle and then return to the world just as it was before you entered the battle.

I couldn’t find anything in the documentation on this but it might just be that I don’t know what terms to search.

I was reading this question HERE and I thought maybe I could accomplish this using a PackedScene but it seems like it might not be the best solution for the problem?

Is there a better way or will a PackedScene be best for what I’m trying to accomplish?

Thanks,
Ben

:bust_in_silhouette: Reply From: eska

You can store the scene (that is, its root node) in some variable, then call remove_child on it (removing it from the tree, effectively freezing it). When you want it back, reinsert it.

Just be careful not to call any functions on the stored scene’s nodes that require them to be part of the tree while it’s removed

EDIT: With PackedScene, be aware that it only saves exported variables. For your problem, that’s probably not what you want.

Thanks so much for the answer. Could you maybe direct me just a bit more with my attempt. I don’t think I have a super great understanding of the scene tree yet. This is what I’m trying:

# I'm using a singleton node here to store the scene
var saved_scene = null

func save_scene():
    saved_scene = get_tree().get_current_scene()

func load_scene():
    if saved_scene != null:
        var root = get_tree().get_root()
        var current_scene = get_tree().get_current_scene()
        root.remove_child(current_scene)
        current_scene.queue_free()
        root.add_child(saved_scene)
        saved_scene = null

I get an error when I try to call queue_free() on the current scene and an error when I try to call add_child on the root (very end). The error messages aren’t very helpful and I’m not sure what I’m doing wrong.

uheartbeast | 2016-05-31 21:38

The saved scene is never removed from the tree, so it can’t be added again, that’s why root.add_child(saved_scene) fails.
current_scene.queue_free() fails because queue_free() can only be called on a node in the tree, while current_scene is removed in the line right before.

Here’s a version that should work as an AutoLoad node:

extends Node

var saved_scene

func switch_scene( temp_scene ):
	# save scene and remove it from the tree
	saved_scene = get_tree().get_current_scene()
	get_tree().get_root().remove_child( saved_scene )
	# instance and add temporary scene as current scene
	var new_scene = load(temp_scene).instance()
	get_tree().get_root().add_child( new_scene )
	get_tree().set_current_scene( new_scene )

func load_scene():
	if saved_scene != null:
		# free temporary scene
		get_tree().get_current_scene().queue_free()
		# add saved scene back to the tree
		get_tree().get_root().add_child(saved_scene)
		saved_scene = null

For this example, I renamed save_scene() to switch_scene() and pass the name of the scene file to temporarily switch to.

Also, keep in mind that _enter_tree() and _ready() are called on all the restored scene’s nodes when the scene is reinserted.

eska | 2016-05-31 23:04

I think this is closer, now it breaks on me when I try and remove the child (line 2 of the switch scene function). It is closer, though, and I appreciate the help. I’ll see if I can work through the errors on my own.

uheartbeast | 2016-06-02 23:04