• Godot HelpProgramming
  • What is the difference between loading a scene and calling .instance() vs class_name and using .new?

I have a scene, Player.tscn. Near the top of Player.tscn, I have "class_name Player"

Now, when instantiating the Player, I have, as far as I see it, two options:

player = Player.new()

or

player = load("res://Player.tscn").instance() as Player

Now, the first version seems best to me...but it clearly isn't. If I use .new(), it claims that it has no children, and any method calls that attempt to get to its children (.get_texture() on a Sprite, e.g.), produces things like "Attempt to call function 'get_texture' in base 'null instance' on a null instance", because apparently Player has a no children, something which a call to .get_child_count() confirms (i.e. it returns 0).

Of course, doing it the second way, everything works fine. But why? Why can't I just use .new() if I've registered it as a class using class_name?

I've asked the question on Stack Overflow as well, but then I realized I've got a much better chance of an answer here. I also read this recent thread, but as it was sort of answering the opposite (though very related) question, it didn't help much.

Welcome to the forums @timdiggerm!

There is a minor, but important difference between the two.

new creates a new instance of the class. It will create a node of the type the class extends, and will return that node (plus the custom script) and place it into the variable. This is useful for when you want to add a new node of a custom type, as you do not have to go through the instancing process to add a custom node to the scene. However, because it is just the class, you only get the node it extends (plus the custom script), nothing else is added.

instance creates a new instance of the scene, which includes the class but also any sub-resources (nodes, textures, etc). While new creates just the node and it's script, instance takes everything in the scene file, duplicates it, and places it into the variable. This means all of the child nodes and other sub-resources are copied and ready to be used. This is helpful for when you want to "spawn" something in, as you often want the entire scene tree. For example, if you are wanting to add a coin to the scene with code, you will want to use instance so the root node, the visuals, collision shape, etc, is added. instance and new are identical if the scene you are instancing has only a single node.

With either method, you still have to add the node(s) to the scene using add_child, as both methods create nodes that exist only in the variable until added as a child of a node.

Hopefully that helps clear it up a bit. I wrote the above quickly, and there are almost certainly better explanations of the differences between the two. Also, there may be other differences, but I just wrote what I have found to be the biggest differences in practice, based on my Godot experience.

Oh that definitely helps! I was doing add_child on both, and that's actually where the errors started popping up - when the _ready() functions started doing stuff to children.

Is best practice, then, to load scenes from a filepath, even if they're registered classes, and then instance? You can't just .instance() on the class name, so it seems like the load is mandatory; I guess I was thinking by registering with class_name I had essentially already preloaded things.

@timdiggerm said: Is best practice, then, to load scenes from a filepath, even if they're registered classes, and then instance? You can't just .instance() on the class name, so it seems like the load is mandatory; I guess I was thinking by registering with class_name I had essentially already preloaded things.

I'd say it depends on what you are doing. If the registered class is a single node that does not rely on sub-resources or child nodes, then using new would probably be best. Otherwise, the recommended way is probably to load the scene using load or preload and then instance it. I'm not sure what is considered best practice though.

I think the registering with class_name is mostly intended for type checking and registering new nodes in the Godot editor, though I could be wrong on that.

3 years later