Hello and welcome to this tutorial on how to instantiate randomly selected objects.

This is a question that pops up every now and then. How do you randomly select a scene out of a group of scenes and then instantiate an object from it. For example if you want to generate a forest or an asteroid field you will need to create several trees or asteroids but they shouldn't all look the same, so you have several tree or asteroid templates and you want to randomly pick one and create a new instance of it.

There are several ways to accomplish this. Usually people will show you the most straightforward one, so I'll quickly show it once and then explain the downsides of that approach. And then I'll show you a couple of alternatives.

So this is the most straightforward solution. Create a scene for the asteroids, add the nodes that make up the asteroid (in this example it's just a Sprite) and set all values that are common for all instances. Leave out those that should be randomly selected. 
These values should be set in the code, so add a script to the root node, and in it add a setup function that takes those parameters that you want to randomly select, in this case the texture file. Inside that setup function assign the values to the corresponding properties, in this case use the value from the texture parameter to set the texture of the asteroid.
We left the texture entry in the inspector empty and now we wrote a function that allows to fill in the blank property from a script.
So now let's go to the game scene where the asteroid will be created. Let's first have a look at the code that creates a new asteroid.
We start by preloading the asteroid scene. This is our template from which we can create new asteroid instances using the instance() function.
We also need to preload the textures that we want to apply to the asteroids.

Now we create a new asteroid instance
Var newAsteroid = asteroidTemplate.instance()
And call the setup function to assign a texture to it. It's this line that achieves the effect we are looking for. With this line we can select a different texture for each asteroid.

Finally we set the new asteroid's position 
and add it to the scene tree, so that it is displayed.

As I said this code is pretty straightforward, since it quite literally performs the same steps that we would have performed manually if we were to create the asteroid field manually. Create a new asteroid, choose a texture and position the asteroid on the screen. The only thing that is different is that in the code we load the scene first, create a new instance next and last attach it to a parent node while in the editor you select the parent node first, then click the instantiate button and then select the scene to be instantiated.

Unfortunately this solution has some downsides. The first one is that the path to the asteroid textures and the path to the asteroid scene are all hardcoded inside the game script. That's not optimal since it means that we would have to change the script everytime a texture file is renamed or moved. And if an artist wants to change a texture or add a new one he or she would have to modify the code.

The second downside is that the game script contains the information which textures can be used for the asteroid. That's clearly breaking object orientation, because the texture of the asteroid is obviously a property of the asteroid, not of the game.

The third downside is that it's now somewhat awkward to edit the asteroid in the editor, since you can't see the textures in the asteroid scene.

So let's see how we can work around these issues. I will not go into too much detail, since in a minute I'll show you a built-in solution that saves a lot of code and trouble.
The first thing we can do is use the export keyword to allow artists to select the textures from the inspector and not have to modify the code.
Next we could move the texture variables from the game script into the asteroid script, so everything that concerns the asteroid is stored in the asteroid scene and its scripts. Now the game could select a texture simply by saying "set up the asteroid using texture number 1". And if the engine understood that code it could even display the asteroid and we could change the texture index.

And that is pretty much exactly what an AnimatedSprite does. So for this second solution I'll use an AnimatedSprite instead of a Sprite for the asteroid. The AnimatedSprite has a property called "Frames" where I can create a new SpriteFrames resource, and when I click the small arrow next to the property I can edit the collection of textures available for this sprite. Once I have done that I can go back to the inspector and simply select the texture using the "Frame" property.

When I want to use this new asteroid scene in the game script I don't even have to change much, since the setup function is basically just replaced by the set_frame function. Instead of calling setup with a texture I just call set_frame with an index. That way the game doesn't need to know anything about the asteroid's textures and the artist can freely modify the selection of textures that should be used for randomly generated asteroids.

If all you want to do is swap the textures of an object this solution is pretty much exactly what you need. But what if your asteroids have colliders and some of the textures have different sizes?
We could go back to setting up the asteroids in the code, but that would be awkward for the artists and game designers. What we need is something that works like the AnimatedSprite. It would have to know all asteroid variations and create one for us, so that in the code we only need to know that one generator object. If you know a little more about programming you will probably have heard of the factory method pattern, which is a pattern that addresses this issue. The idea is that you write a method that receives any kind of parameter, like the name of an object to be generated or generation parameters in any custom format you like, and returns a new instance of the corresponding object.
And that's what we are going to look at now.

Basically a factory method consists of two parts: The information what each creatable object looks like and a way of selecting one object to be created. So let's start by creating a scene that contains one instance of each asteroid version.
Next we need to write the actual factory method, that is a method that returns a new instance of one asteroid. And that is easier than it may sound: just get one of the child nodes and return a duplicate of it.
As a last step we need to modify the script that creates the asteroids in the game scene.
This time we start by preloading the factory scene and creating an instance of it. But unlike before we are not going to add it to the scene tree. There's no line calling add_child since we don't want the factory to be visible, it's just meant to exist inside this variable. That way all the factory is not visible but we can still call its functions, in this case the generate_asteroid-function we wrote before.

So this line creates a new asteroid using the first template:
Var newAsteroid = factory.generate_asteroid(0)
The rest of the code is the same as before, we set a position for the new asteroid and add it to the scene tree.

This way you have one scene where you can see and edit all asteroids, and the asteroids can be as similar or different as you need them to be.
Also the game code doesn't contain any information about the asteroid templates, so you won't need to adjust the game script when you change the asteroid templates.


