How can I pass parameters to a scene before change scene?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By elahehab

Hi,
I have a scene that repeats multiple times - lets say travel.tscn - in my game but with different parameters (like different texts) I want to change the scene to travel.tscn but before that I want to set those parameters. I searched and didn’t find any solution. For now I use global node. I defined some parameters in global.gd and I set them before change scene and I read them in travel.tscn. Is there a better method for doing this?

:bust_in_silhouette: Reply From: scrubswithnosleeves

Hey,

That is the best method! Are you having any issues using that method, or did you just not think that was the best way?

I think this is not a good method! Now I have another scene that has parameters. These parameters are mixed and it causes so many bugs! I think this is a really simple feature that Godot should have!!

elahehab | 2020-12-23 11:30

:bust_in_silhouette: Reply From: SourSaltSit

Autoload singleton’s are one solution, but it does feel akward having more state just floating around in some global. Another solution is to handle the scene change yourself:

To get finer control over changing scene, you’ll have to add and remove scenes directly with sceneTree.add_child and sceneTree.remove_child(or delete the node with free() or hide it’s visibility). They’re a couple of ways to do this in the docs.

Basically:

  1. Instantiate your scene directly
  2. Parameterize your new scene
  3. Add it to the sceneTree
  4. Remove/delete/hide the last scene
    In code this would look something like:
# We instantiate the scene before we add it 
var travel_scene = load("res://travelScene.tscn").instantiate();
# parameterize the scene
travel_scene.location = "Hell"
# Add the scene as a child to the sceneTree
get_tree().get_root().add_child(travel_scene)
# Delete the last level
# You could also hide it's visibility or hard delete it
# You're use-case will determine which.
get_tree().get_root().remove_child(last_level)