I am currently working on my game's save and load states, and I created a global script to use it. In the script, I preload the player scene and then later in the load_game() function I instance it. And the instance doesn't seem to work.
I get the error "Invalid call. Nonexistent function 'instance' on base 'Nil'". I have tried to use load instead of preload (didn't work). This is my first time making save and load states so I am bit puzzled about how to access the player scene in a global script.
Here is the code:
onready var playerCharacter = preload("res://Player/Player.tscn").new()
This line here is getting the error:
var player = playerCharacter.instance()
Thanks in advance for any help. I'd appreciate any godot docs that can help me understand this and also help me in saving and loading my game. Currently I am using .dat files I learnt from GameEndeavor.
This expression:
preload("res://Player/Player.tscn")
If the path is correct, will give you an PackedScene
object.
This expression:
preload("res://Player/Player.tscn").new()
I'm surprised it is not giving you an error. The new
method is static, and should not be called on an object. From the error you got, I'm gessing this is returning null
.
You can use preload
, but with a const
like this:
const playerCharacter = preload("res://Player/Player.tscn")
This is possible because preload
keyword gives you constant expression and it is resolved while parsing. And it should also make Godot complain if you add something that is not a constant expression such as .new()
.
If you use load
then you can't use const
, however it should also work. Using load
will load the PackedScene
when Godot executes the line. Using preload
Godot will load the PackedScene
when Godot loads the script. You might also be interested in the ResourceLoader
class.
Once you have your PackedScene
object, you should be able to call instance
on it:
var player = playerCharacter.instance()
For future reference: in Godot 4 it is instantiate
.
To satisfy curiosity and clear confusion… You can create a PackedScene
with new
like this:
var packed_scene := PackedScene.new()
But only do that if you wanted to create an scene from code. Which you can save to a file using the ResourceSaver
class. For example:
var packed_scene := PackedScene.new()
packed_scene.pack(node)
ResourceSaver.save("res://new_scene.tscn", packed_scene)
Which might be useful, for example, when running code from the editor (perhaps as part of a plugin), but that is not what you are doing here.