Randomly selecting between 2 scenes

Godot Version

Godot 4.4.1

extends Node2D

var array = [preload("res://egg.tscn"), preload("res://broken_egg.tscn")]
var eggcount = 0
func _process(delta: float) -> void:
	if eggcount == 0:
		array.pick_random()
		var scene = array.instantiate()
		add_child(scene)

Question

Hey! Im trying to randomly select between 2 scenes or i guess 2 versions of eggs i want to spawn. I wrote this code but it doesnt seem to work…
It gives an error upon debugging. I couldnt find any solutions online can someone help me?

When you post questions here, the more information you give us about the problem and what you tried to fix it yourself before posting, the more helpful the answers will be.

If I were to write a reply like the question you posted, I would tell you that you haven’t given us enough information and leave you to figure out what information you’re missing.

Instead I’m going to tell you that if you want us to help you debug an error, that you need to copy and paste the error message here. It would also be helpful to tell us why you decided to put this in the _process() function

1 Like

Im a new dev and this is my first post.
The error message is: Invalid call. Nonexistant function ‘Instantiate’ in base ‘Array’
i put it in _process because im going to spawn eggs every 5 seconds (im going to add that code later)

pick_random() returns a variant value. You are calling it and not using the returning result.
Without fully testing on my end, I beleive this will work.

var array = [preload("res://egg.tscn"), preload("res://broken_egg.tscn")]
array.pick_random().instantiate()

or

var array = [preload("res://egg.tscn"), preload("res://broken_egg.tscn")]
var scene = array.pick_random()
scene.instantiate()
2 Likes

I figured. That’s why I took the time to explain how to get the best answers.

Ok the error message tells you what the problem is. You’re trying to create an object from the array itself instead of one of the items in it.

And @GameDevGeezer gave you a couple solutions that should solve your problem.

When you do, I’d recommend you look at adding a timer that runs every 5 seconds and spawns an egg when the timer expires every 5 seconds. _process() is called 60 times a second. So it’s being checked 300 times for every one time that it actually does something.

I’ve added a timer and did what @GameDevGeezer wrote, but i still couldnt get it working.

func _on_timer_timeout() -> void:
	print("test")
	var scene = array.pick_random()
	scene.instantiate()

I’ve used the print() command to make sure the timer works however the instantiate() doesnt work

Hello!

Could you explain how the “instantiate()” does not work?

I’m going to guess that the selected scene doesn’t appear anywhere and in that case, remember to add the scene as a child to a node, such as your main scene.

(In your original code snippet you have “add_child(scene)”, which you do not seem to have in your new code snippet.)

The egg scenes are added to the main scene and the reason why add_child(scene) isnt in my current code snippet is i followed @GameDevGeezer’s code which happened to not have that.
If you also read the previous replies you can understand that im currently trying to learn why instantiate() doesnt work so i dont really know how it doesnt work

What do you want the “instantiate()” to do? How is it not working? Is it crashing or is seemingly nothing happening?

“instantiate()” (said simply) creates a node using a PackedScene resource, which then needs to be added to the scene using “add_child” (or other similar function).

For more info (“Instancing scenes” -segment):

Nothing is happening plus ive tried the godot document and it still didnt work

instantiate() returns an orphan, which means it is not visible on screen because it is not on the scene tree, you then need to add it via add_child(), also if you can’t see it, it’s probably because you didn’t give it a position so it will default to x:0 and y:0 be offscreen probably

you’re instanciating the scenes but you are not changing the scene to any of them you have the instances you need to call a method on the tree to change the scene
get_tree().change_scene_to_file(scene)

im trying to add the scene to the main scene not change it completely if thats what you are trying to say

I’ve used an RNG to achieve what i wanted however i couldnt get the instantiated egg area2d signal to connect to the main script
heres my code that is working:

extends Node2D
var rng = RandomNumberGenerator.new()

func _on_timer_timeout() -> void:
	print("hey")
	var randomnumber = rng.randi_range(1, 2)
	if randomnumber == 1:
		var spawn = egg.instantiate()
		add_child(spawn)
		spawn.linear_velocity.y = -30
		
	elif randomnumber == 2:
		var spawn2 = brokenegg.instantiate()
		add_child(spawn2)
		spawn2.linear_velocity.y = -30
1 Like

glad you figured it out !
randi_range(value, value)
works as a standalone you don’t need to create an rng object atall !

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.