How can I make a dispenser that emits a given type of element?

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

I am creating a dispenser that should be able to spawn anything (enemies, power-ups, etc.)

Fo now, I have this code:

extends Node2D


export(float) var delay: float = 1.0
export(PackedScene) var dispense: PackedScene

func _ready() -> void:
	$Timer.wait_time = delay

func _on_Timer_timeout() -> void:
	var newElement = # This doesn't work

func _get_configuration_warning() -> String:
	if dispense == null:
		return "%s needs an element to dispense" % name
	return ""

The dispense attribute is the thing that is supposed to be emmited every delay seconds.

How do I instanciate a new element based on its type? I tried, but it doesn’t work (Invalid call. Nonexistent function ‘new’ in base ‘PackedScene’. when interpreted).

How do I instanciate it?

:bust_in_silhouette: Reply From: AlexTheRegent

You need to use instance() method instead of new(). new() is for scripts, instance() is for nodes.

Amazing, it works like a charm. Thanks!

SteeveDroz | 2021-02-26 17:57

:bust_in_silhouette: Reply From: Inces

You need to create class in order to instantiate it using New().
Take script of your dispenser and define its class by class_name keyword, followed by your chosen name, for example : class_name dispenser, no more syntax. It should be first line of code right after “extends” keyword.

From this moment You can refer to this class from any script, You don’t need to preload it or encrypt within variable. And this will be possible :

func _on_Timer_timeout() -> void:
        var newelement = dispenser(new)

Nice to know, but it doesn’t answer the question. I was looking for a way to instanciate a PackedScene, not the current class. AlexTheRegent answered my question perfectly.

SteeveDroz | 2021-02-26 18:00