@Sosasees said:
@TwistedTwigleg said:
You can add an autoload script that adds the scene as its child, which effectively would keep the scene in memory for the entire duration of the game. It is probably not the best solution, but it should work in a pinch.
I'm looking for a long-term solution.
In that case, I would probably still suggest using an autoload script, but I would add some helper functionality to avoid some potential pitfalls that could come back to bite you later.
The first thing I'd recommend for a long-term solution is making sure there is a condition to make sure the autoload you are wanting to add does not already exist, as this could be a issue later that would be hard to debug. It likely won't crop up, but if it does, you'll save yourself some trouble down the road
I would also add a function so you can get a reference to the scene from the function, so if you need to change things later, it should be easier since there are no hard-coded paths.
Thankfully, all of this should be fairly easy to do. Here's how I would approach it:
extends Node
const AUTOLOAD_ID = "insert_a_unique_id_here"
const desired_scene_file = preload("res://path_to_scene.tscn")
var desired_scene = null
func _ready():
# make sure the autoload does not already exist
# I think the follow code should do it, but it's been awhile since I've worked with autoloads.
for root_child in get_tree().root.get_children():
if "AUTOLOAD_ID" in root_child:
if root_child.AUTOLOAD_ID == AUTOLOAD_ID:
queue_free()
return
# add the scene to the autoload.
desired_scene = desired_scene_file.instance()
add_child(desired_scene)
func get_desired_scene():
if desired_scene == null:
print ("WARNING: Autoload does not have the desired scene! Returning null...")
return desired_scene
Then when you are using it, you can do something like the following:
# We'll assume the autoload has been named "autoload_node" in the project settings
var desired_scene = autoload_node.get_desired_scene()
if desired_scene != null:
desired_scene.do_something()
That said, there may be better/easier ways to handle this, but that is probably how I would go about it, if this were my project. The only issue with this method is that garbage collection will not clean up the scene (which is probably not an issue since you need it everywhere), and any executions running on these nodes will not be interrupted when changing scenes. To fix the execution issue, you can add a function to change scenes to the autoload that handles stopping the scene:
func custom_load_scene(scene_path):
# two ways to do this. Either have a function that will stop the execution
# or delete the node and then add it after loading.
# You can also use both, if you want (that's what I've done here)
if desired_scene != null:
if desired_scene.has_method("_on_scene_change":
# call a function that can be implemented to stop execution of processes!
desired_scene._on_scene_change()
# delete the node
if desired_scene != null:
desired_scene.queue_free()
desired_scene = null
get_tree().change_scene(scene_path)
# add the node back!
if desired_scene == null:
desired_scene = desired_scene_file.instance()
add_child(desired_scene)