How to pass parameters when instantiating a node

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By sandheaver
:warning: Old Version Published before Godot 3 was released.

I have a simple scene that contains a Sprite node as its root. The sprite node has a SamplePlayer2D as a child.

I am a bit confused about how to pass ‘constructor’ parameters to this Sprite node when instantiating it from inside another scene. If I use …

var mySprite = preload("res://mySprite.scn").instance() get_parent().add_child(mySprite)

… I seem to have no way to pass any parameters to the sprite’s _init() function. if however I use…
var mySprite = preload("res://scripts/mySprite.gd")
mySprite.new(param_a, param_b)
get_parent().add_child(mySprite)

… then the sprite’s child sample player is not created with it, as the whole packed scene has not been instantiated. I have a feeling I’m approaching the whole task the wrong way.

As far as I know passing arguments for the constructor of scripts that are deriving from the Node class is prohibited simply because editor needs to know how to construct given node. Do what @atze suggested, or use exported variables and init object in ready.

kubecz3k | 2016-06-02 13:01

:bust_in_silhouette: Reply From: atze

There probably are better ways to do this but here is what I did:

Create your own init() function in mySprite.gd and call it after instancing the scene.

var mySprite = preload("res://mySprite.scn").instance()
mySprite.init(a, b)
getparent().add_child(mySprite)

Yes that’s the good solution, as kubecz3k mentioned passing arguments to an instanced node constructor is not supported, because it would make it impossible to instance via the editor (which won’t ask you to give the required arguments values).

So using a custom init() or setup() function is the simplest solution to achieve this behaviour.

Akien | 2016-06-03 07:50

Thanks all !

sandheaver | 2016-06-03 10:38

If this has answered your question, please select it as such

atze | 2016-06-03 17:58

I like to make init(...) return self, so I can do:
var mySprite = preload("res://mySprite.scn").instance().init(...)
I also like to preload the script into a constant, just in case I need to use it more:
const MySprite := preload("res://mySprite.scn")
var mySprite = MySprite.instance().init(...)

MonsterVial | 2020-10-08 21:39

@MonsterVial Glad I read this

Belaidev | 2020-11-26 01:53

:bust_in_silhouette: Reply From: CKO

In Godot 3.0 you would do this as follows:

In MySprite.gd:

func _init(param_a, param_b):
    #do your init

In another scene:

MySprite = preload("res://scripts/MySprite.gd")

var mySprite = MySprite.new(param_a, param_b)

You might have misread or have not read all of the question. It’s about initializing a Node not a Script.
You’ve written something similar to the lower part of the question, which explains why it doesn’t work.

Dlean Jeans | 2019-02-22 07:25

I know this wasn’t supposed to be the answer for the question, but it helped me thanks!

God bless guys.

VastView | 2021-08-24 02:18

In 3.4 this causes an error. “Invalid call. Nonexistent function ‘new’ in base ‘PackedScene’.”

wetbadger | 2022-03-30 18:28

That’s because you are instantiating a scene. This example is for instantiating scripts.

edzillion | 2022-07-29 13:28