I am currently working on my game's save and load states, and I created a global script to use it. The script extends Reference class and uses the .dat file extension for saving and loading files. But I can't use the method get_tree()
in the script.
I get the error: The method get_tree() isn't declared in the current class.
I think the problem is that Reference is not connected to the SceneTree. So I tried using a player instance and use get_tree() on that like this:
const PLAYER_CHARACTER = preload("res://Player/Player.tscn")
var player = PLAYER_CHARACTER.instance()
player.get_tree().change_scene("res://Map/" + player_data.scene)
But then I get this error: Attempt to call function 'change_scene' in base 'null_instance' on a null instance.
I am a little confused on how to change the scene from this script when I load a save file. I need this to complete my save and load states. The code is here:
extends Reference
get_tree().change_scene("res://Map/" + player_data.scene)
I appreciate any kind of explanation on why this is the case and any godot docs that can help me better understand this issue.
The method get_tree
exists in Node
(and derived classes). Notice that Node
s exists in the scene tree.
However Reference
has no relationship with the scene tree.
Furthermore, news: You can create, from code, multiple SceneTree
s (not something you need to do for 99.99% of games, but the option is there).
Therefore, it is not a concern of Reference
to be able to get the SceneTree
, and if it were, it won't be clear which one to get.
The issue with this code:
const PLAYER_CHARACTER = preload("res://Player/Player.tscn")
var player = PLAYER_CHARACTER.instance()
player.get_tree().change_scene("res://Map/" + player_data.scene)
Is that get_tree()
gives you null
because the instance player
is not in a SceneTree
.
Now, presumably you want the default SceneTree
. For that there is a work around:
var scene_tree := Engine.get_main_loop() as SceneTree
The SceneTree
class extends the MainLoop
class. And by default, the main loop of Godot uses an instance of SceneTree
.
So the above line of code would work unless you changed the type of the main loop to something else. Which, again, you can (probably not something you would do for a game, but for some utility applications it makes sense - Yes, using Godot for non-game software).
With that said, I would like to encourage you to look for a different design. For changing the current scene we would often use an Autoload (singleton), which become available from everywhere in the scene tree, plus they persist when the scene changes.
Keep in mind that extending Reference
will make your class reference counted.