#4 Place Prefab in a Random Position of the Stage

Updated information about this project

This arti­cle belongs to a series that con­sist on mak­ing a first per­son game about find­ing objects inside a maze. It's one of my very first series from the chan­nel. Now I reworked this project and you can down­load it to import in your own Uni­ty project. Some day I will make a new series about this project, sub­scribe to my chan­nel to see all the fresh con­tent about Blender, Uni­ty and pro­gram­ming.

Follow me on itch.io and download the source code of this project

YOU CAN TRY THIS GAME HERE, IT MAY TAKE A LITTLE WHILE TO LOAD
🔻

MOVEMENT: WASD CAMERA LOOK: MOUSE

Introduction of the old article

In this arti­cle we ana­lyze the video 4 of the series My First Game in Uni­ty. In this video we cre­at­ed the first Script that will be in charge of plac­ing a Pre­fab ran­dom­ly on the stage. The Pre­fab that we are going to place is the first per­son con­troller FPSCon­troller of Stan­dard Assets.

We will place the char­ac­ter in front of a door and as there will be sev­er­al of them on the stage, we will have to make a ran­dom choice.

Go to the project's Main Page

Video related to this article


Spawn point of the character

We began by assem­bling with the pre­fab­ri­cat­ed a scene like the one shown in fig­ure 1.

escena de unity 3d en la que se observa un suelo de cesped con margaritas y cuatro portales.
Fig. 1: Ini­tial arrange­ment of objects in the scene.

We cre­at­ed an emp­ty GameOb­ject that we're going to use to mark the posi­tion where the play­er will appear at the start of the game.

crear empty game object en unity 3d. modelo 3d de un portal
Fig. 2: A new Emp­ty GameOb­ject is cre­at­ed to assign the Script.

We are going to call this object "Spawn­Point".

unity 3d se observa un atardecer y un suelo de cesped con margaritas
Fig. 3: The new GameOb­ject will have the name "Spawn­Point".

In the inspec­tor we can choose an icon to bet­ter visu­al­ize the GameOb­ject in the scene.

selección de ícono para gameobject en unity 3d
Fig. 4: We can assign an icon to the GameOb­ject to bet­ter visu­al­ize it in the scene.

empty gameobject en unity 3d con ícono asignado.
Fig. 5: The GameOb­ject is now dis­played with the label selected.

We will cre­ate a new Tag to assign to this GameOb­ject. At the top of the inspec­tor we have a drop-down menu called Tag, click­ing allows us to choose a Tag to assign or cre­ate a new one with "Add Tag". We click on this option.

menu para añadir tag en en unity 3d.
Fig. 6: Menu for assign­ing an exist­ing Tag or cre­at­ing a new one.

In the win­dow that appears click on the plus sign and type the name of the Tag. It is impor­tant to note the use of cap­i­tal letters.

crear nuevo tag en unity 3d.
Fig. 7: We cre­at­ed a new Tag called SpawnPoint.

We select again the GameOb­ject "Spawn­Point" from the hier­ar­chy and in the Tag menu we select the Tag "Spawn­Point" that we just created.

seleccionar tag en unity 3d.
Fig. 8: Assign the cre­at­ed Tag to the GameOb­ject "Spawn­Point".

Creation of the first Script

Final­ly we are going to start pro­gram­ming in C#. To start we need to cre­ate a C# Script, for this we right click on a fold­er in the project (I sug­gest the Script fold­er we cre­at­ed to orga­nize our­selves), then we go to Cre­ate > C# Script, as shown in Fig­ure 9.

crear script c# en unity 3d.
Fig. 9: Cre­ation menu, select C# Script.

We're going to name the file "Game­Con­trol" because it will con­trol the fun­da­men­tal aspects of our game. The file that is cre­at­ed can be seen in fig­ure 10.

script c# en unity
Fig. 10: The new script is called Game­Con­trol with­out spaces.

Pro­gram­ming usu­al­ly uses a way of writ­ing as shown in Fig­ure 10, is known as Camel Case and con­sists of elim­i­nat­ing spaces and dis­tin­guish words using cap­i­tal letters.

We use this nota­tion for script names, vari­ables and methods.

Before start­ing to pro­gram, let's select a Scripts edi­tor, click on Edit > Preferences.

ventana de preferencias de unity 3d
Fig. 11: Uni­ty pref­er­ences win­dow, select the Mon­oDe­vel­op editor.

For the series My First Game in Uni­ty we used the script edi­tor Mon­oDe­vel­op, this edi­tor was dis­con­tin­ued, that's why in the Fun­da­men­tal Series of Uni­ty Visu­al Stu­dio is used.

selección de editor de scripts en unity 3d.
Fig. 12: You can choose the edi­tor you like the most, cur­rent­ly the default edi­tor is Visu­al Studio.

When open­ing the Script to edit we find some code already written.

In fig­ure 10 the first 3 lines that begin with the word "using" are used to import libraries that will allow us to access cer­tain functionality.

Then comes the def­i­n­i­tion of a class that bears the name we gave to the Script, in this case Game­Con­trol. It also indi­cates the super class, ie the class from which inher­its its behav­ior, in this case MonoBe­hav­iour. So all the attrib­ut­es and meth­ods of the MonoBe­hav­iour class will be avail­able for us to use.

The pre­vi­ous para­graph has sev­er­al object-ori­ent­ed pro­gram­ming con­cepts that do not make sense to delve into this arti­cle, because it is a fair­ly exten­sive top­ic. How­ev­er, I believe that the men­tion of words such as "class", "attrib­ut­es" or "super class" may arouse curios­i­ty and encour­age the read­er to inves­ti­gate the sub­ject fur­ther. At this time I do not have arti­cles on object-ori­ent­ed pro­gram­ming, although I wish to write them soon.

Then there are two meth­ods defined, the Start method and the Update method. The Start method will run auto­mat­i­cal­ly once when the game starts and the Update method will run auto­mat­i­cal­ly once in each Frame in the game.

script c# genérico en unity 3d.
Fig. 13: View of a new­ly cre­at­ed script.

In the region that is between the def­i­n­i­tion of the class and the def­i­n­i­tion of the Start method we are going to place all the attrib­ut­es of the class, that is to say all the vari­ables and objects that we will use so that the Script ful­fills its func­tion­al­i­ty. Some time ago I wrote an arti­cle about the basic types of vari­ables that we are going to use in the tutorials.

Let's write two lines of code, the first is "Seri­al­ize­Field" in square brack­ets, this is to tell Uni­ty that what comes next is a field to be seri­al­ized. With­out going into detail this line will make pri­vate fields (vari­ables or objects) appear in the inspector.

The next instruc­tion is "pri­vate string tag", with this we are declar­ing a vari­able of type string of name "tag" with pri­vate visibility.

Vis­i­bil­i­ty is also an object-ori­ent­ed pro­gram­ming theme, used to hide attrib­ut­es or meth­ods that are not acces­si­ble from a con­text out­side the class. Attrib­ut­es or meth­ods with pub­lic vis­i­bil­i­ty are acces­si­ble from oth­er classes. 

script c# genérico en unity 3d. definir variables
Fig. 14: A String vari­able called "tag" is defined. 

Asignar Script has a GameObject

For the code to be exe­cut­ed it is not enough to cre­ate a Script, we must assign it to at least one GameOb­ject of the hierarchy.

Game­Con­trol will be in charge of con­trol­ling the basic aspects of the game. In prin­ci­ple it could be assigned to any GameOb­ject that is present dur­ing the whole game, but for a bet­ter orga­ni­za­tion we are going to cre­ate an Emp­ty GameOb­ject that we will call "Con­trol".

crear empty game object en unity 3d
Fig. 15: We cre­at­ed a new emp­ty GameObject.

With the new GameOb­ject select­ed, we drag the Game­Con­trol Script into the inspec­tor to add it as a component.

renombrar game object en la jerarquía de unity 3d
Fig. 16: The new GameOb­ject will be called Control.
asignar script c# en el inspector en unity 3d
Fig. 17: We can drag the Game­Con­trol Script into the hier­ar­chy of the Con­trol object to assign it.

Fig­ure 18 shows that the script has been added as a com­po­nent to the Emp­ty GameOb­ject Control.

inspector en unity 3d
Fig. 18: Script is now a com­po­nent of the Con­trol object.

Anoth­er way to accom­plish this is by using the Add Com­po­nent but­ton and search­ing for the Game­Con­trol Script. 

add component en unity 3d
Fig. 19: Anoth­er way to assign the Script is through the Add Com­po­nent button.

The rea­son why in fig­ure 18 we don't see the String "tag" that we define is because we don't save the changes in the Script. In fig­ure 20 you can see that in the Script tab there is a cir­cle instead of a cross, this means that there are unsaved changes, you can eas­i­ly save by press­ing CTRL‑S.

It is advis­able to save fre­quent­ly enough so that in case of pos­si­ble fail­ures we do not lose our work.

definicion de variables que se encargarán de colocar el prefab aletoriamente unity 3d.
Fig. 20: The cir­cle on the tab indi­cates that there are unsaved changes.

After sav­ing the changes we see in the inspec­tor the string "Tag". In this field we are going to write "Spawn­Point" which is the name we gave to the tag we assigned to GameOb­ject Spawn­Point (fig­ures 5 to 8).

Fig. 21: The seri­al­ized string Tag appears in the inspector.
Fig. 22: We can write a val­ue for the String.

Place character prefab randomly

The char­ac­ter will def­i­nite­ly be a GameOb­ject, in par­tic­u­lar the Pre­fab FPSCon­troller from Stan­dard Assets. We have to tell Uni­ty some­how which pre­fab we want to put on stage.

For this we are going to define a pri­vate GameOb­ject that we will call "play­er­Pre­fab" and we will indi­cate it as seri­al­iz­able so that it appears in the inspector. 

Fig­ure 23 shows the two instruc­tions that allow you to do this.

definicion de variables que se encargarán de colocar el prefab aletoriamente unity 3d.
Fig. 23: We define a GameOb­ject to save the Pre­fab of the char­ac­ter to instantiate.

In pre­vi­ous videos we had cre­at­ed a Pre­fab of the FPSCon­troller and we had placed it in Assets > Pre­fabs > Char­ac­ter. This is the Pre­fab that we are going to place on the stage.

prefab a colocar aleatoriamente en unity 3d
Fig. 25: The pre­fab FPSCon­troller from Stan­dard Assets will be our character.

We take the Pre­fab FPSCon­troller and drag it to the new field in the inspec­tor, as shown in fig­ure 24.

Fig. 24: We assign the pre­fab in the new space in the inspector.

It's very impor­tant that we keep the ref­er­ence of the player's GameOb­ject, for exam­ple to destroy it when the game is over. We are going to do this by defin­ing a new pri­vate GameOb­ject that we will call "play­er".

In this case we will not mark this field as seri­al­iz­able, because it is for inter­nal use of the Game­Con­trol Script.

definicion de variables que se encargarán de colocar el prefab aletoriamente unity 3d.
Fig. 26: We define a pri­vate GameOb­ject to save the ref­er­ence of the char­ac­ter we place in the scene.

Then we need to know where we're going to put the char­ac­ter on stage. For this we cre­at­ed the Emp­ty GameOb­ject that we call Spawn­Point (fig­ures 2 to 5). We are going to make it the son of a door and cre­ate a Pre­fab of the door with the object SpawnPoint.

So each door will have its own Spawn­Point. If we have only one door in the stage, the char­ac­ter will appear in that place, but if we have four doors (as it will be in our case) the char­ac­ter will be able to appear in any of them randomly.

First we need the GameOb­ject Spawn­Point ref­er­ence, but how many? Since we don't want to lim­it the func­tion­al­i­ty of this script to a fixed num­ber of doors, we'll sim­ply make it auto­mat­i­cal­ly detect how many points of appear­ance there are and choose one of them ran­dom­ly with the same probability. 

We are going to define a vec­tor or array of GameOb­jects, that is to say a struc­ture of data that con­tains sev­er­al ordered GameOb­jects, which we will be able to access with an inte­ger val­ue that will indi­cate its posi­tion in the array.

To define this array we use the word GameOb­ject fol­lowed by square brack­ets, as illus­trat­ed in fig­ure 27. As this array will con­tain all the points of appear­ance of the sce­nario I will call it "spawn­Points" and I will also define it as pri­vate and a Seri­al­iz­able field.

definicion de variables que se encargarán de colocar el prefab aletoriamente unity 3d.
Fig. 27: A GameOb­jects Array is defined to save the ref­er­ence of all the points of appear­ance in the scene.

In the inspec­tor you can see what this data struc­ture looks like. It appears as a drop-down menu that has an inte­ger val­ue called "Size", which will indi­cate the size of the array.

As can be seen in fig­ure 29, if we write a num­ber in this vari­able, we see that there are that many GameOb­jects fields.

En este pun­to podríamos hac­er que la vari­able Size sea igual a 4 y asig­nar man­ual­mente todos los pun­tos de apari­ción, pero no quer­e­mos estar lim­i­ta­dos a eso, quer­e­mos lograr que cuan­do agregue­mos o quite­mos una puer­ta, la selec­ción del pun­to de apari­ción se haga automáticamente.

Fig. 28: Dis­play of the Array in the inspec­tor, we can indi­cate the size of the Array.

Fig. 29: When defin­ing the size of the Array, the fields to fill in appear. We could man­u­al­ly place the appear­ance points.

We will define a new GameOb­ject that will have the ref­er­ence of the cho­sen point of appear­ance, we will call it "select­edSpawn­Point" and we will make it pri­vate and seri­al­iz­able to be able to observe it in the inspector.

definicion de variables que se encargarán de colocar el prefab aletoriamente unity 3d.
Fig. 30: Define a GameOb­ject to save the ref­er­ence of the ran­dom­ly select­ed point of appearance.

Programming the behaviour

Until now we have been defin­ing the objects we will need, now we will begin to write instruc­tions that are the ones that will make things hap­pen in our game.

The first instruc­tion will be placed in the Start method and will be respon­si­ble for find­ing all the points of appear­ance on the stage and save them in the "spawn­Points" array.

Fig­ure 31 shows that the edi­tor helps us by sug­gest­ing code as we write. If this doesn't hap­pen it could be for two rea­sons, the option "code-auto­com­plete" is deac­ti­vat­ed in the configuration. 

The oth­er rea­son may be a bug in the edi­tor, or that Uni­ty is not con­nect­ed to the edi­tor. If this hap­pens, try to solve it because not only will we not have the code sug­ges­tion but we will not have syn­tax analysis.

instrucciónes c# que se encarga de colocar el prefab aletoriamente unity 3d. findgameobjectwithtag
Fig. 31: As we write code the edi­tor sug­gests vari­ables or meth­ods that start with what we write.

To find the ref­er­ences of the points of appear­ance we are going to use a method of the GameOb­ject class that will allow us to find objects using its tag.

In fig­ures 31 and 32 we see that there are two vari­ants of this method, one returns a sin­gle GameOb­ject (fig­ure 31) and the oth­er returns an array con­tain­ing all GameOb­jects that have the tag we indi­cate (fig­ure 32). 

Notice how these two meth­ods are only dif­fer­en­ti­at­ed by an "s" letter.

instrucciónes c# que se encarga de colocar el prefab aletoriamente unity 3d. findgameobjectwithtag
Fig. 32: We are going to use the Find­GameOb­jectsWith­Tag method of the GameOb­ject class.

The instruc­tion would then be as follows:

spawnPoints=GameObject.FindGameObjectsWithTag(tag);

instrucciónes c# que se encarga de colocar el prefab aletoriamente unity 3d
Fig. 33: The instruc­tion in the Start method is respon­si­ble for find­ing all the points of appear­ance of the sce­nario and sav­ing them in the Array spawnPoints.

In the sec­ond video of Unity's fun­da­men­tal series I ana­lyze this way of find­ing GameOb­jects ref­er­ences and four oth­er ways. I also wrote an arti­cle about that video going deep­er into the information.

Fig­ure 34 shows that when enter­ing game mode, our array is size 1 and con­tains the GameOb­ject Spawn­Point ref­er­ence of the hier­ar­chy (high­light­ed in yel­low by Uni­ty itself).

Fig. 34: When enter­ing the game mode, we see that in the inspec­tor is the ref­er­ence of the point of appearance. 

Let's cre­ate some copies of this GameOb­ject with CTRL‑D and go back into game mode.

Fig. 35: Copies of the points of appear­ance are created.

Now we can see that the array is of size 4 and con­tains all the ref­er­ences of the GameObjects.

Fig. 36: When enter­ing the game mode again, the Array now has four ele­ments and all ref­er­ences are present.

We put a Spawn­Point in every door.

colocar prefab aleatoriamente. posicionar empty objects
Fig. 37: We place a point of appear­ance on each door.

Select a random element from the array

To choose a ran­dom spawn point we need to ran­dom­ly choose an ele­ment from the array. This will be done by defin­ing an inte­ger vari­able named "rand" that will be equal to a ran­dom num­ber between 0 and the num­ber of ele­ments of the array minus 1.

This last part is so because in C# the first ele­ment of the array has the posi­tion 0 and the last one the posi­tion "Length‑1" (size of the array minus 1).

To gen­er­ate a ran­dom inte­ger we use the Range method of the Ran­dom class and indi­cate two para­me­ters, the begin­ning of the inter­val (val­ue that is includ­ed) and the end of the inter­val (val­ue that is exclud­ed). As shown in fig­ure 38.

instrucciónes c# que se encarga de colocar el prefab aletoriamente unity 3d
Fig. 38: The sec­ond instruc­tion gen­er­ates a ran­dom inte­ger between 0 and the num­ber of appear­ance points minus 1.

Notice how the range of val­ues for this num­ber will auto­mat­i­cal­ly adjust to the num­ber of occur­rence points in the hierarchy.

The next step is to obtain the ref­er­ence of the point of appear­ance that is in the posi­tion that defines that ran­dom inte­ger. To access the com­po­nent of an array we use the name of the array and between square brack­ets the whole num­ber of the position.

The ele­ment of the array is assigned to the GameOb­ject select­edSpawn­Point pre­vi­ous­ly defined. We can see this in fig­ure 39.

instrucciónes c# que se encarga de colocar el prefab aletoriamente unity 3d
Fig. 39: The third instruc­tion selects the point of appear­ance of the array.

In fig­ures 40 and 41 we see two tests of the game in which a dif­fer­ent point of appear­ance has been chosen.

Fig. 40: In this test the spawn point is D.
Fig. 41: In this test the spawn point is B.

The next step is to place the character's pre­fab in the posi­tion of the select­ed appear­ance point.

For this we are going to use the Instan­ti­ate method of the MonoBe­hav­iour class (super class of GameControl). 

The fourth video in Unity's fun­da­men­tal series is about the Instan­ti­ate method, although that video is some­what strange, the arti­cle explains in detail how the method works.

The Instan­ti­ate method has sev­er­al ver­sions, we are going to use one that requires the Pre­fab to instan­ti­ate, the posi­tion where it is going to be placed and the rota­tion it will have.

For the pre­fab we had defined the GameOb­ject "play­er­Pre­fab". While the posi­tion and rota­tion will be read from the GameOb­ject "select­edSpawn­Point".

The exe­cu­tion of the Instan­ti­ate method will return a GameOb­ject which will be the ref­er­ence of the cre­at­ed GameOb­ject, i.e. the ref­er­ence of the play­er. We are going to save this ref­er­ence in the GameOb­ject "play­er", because we will prob­a­bly use it later. 

What was explained in the last three para­graphs is illus­trat­ed in the last instruc­tion in fig­ure 42.

instrucciónes c# que se encarga de colocar el prefab aletoriamente unity 3d
Fig. 42: The fourth and final instruc­tion places the character's pre­fab at the cho­sen point of appearance.

As an obser­va­tion, we can men­tion the use of the point oper­a­tor to access the posi­tion and rota­tion attrib­ut­es, which are defined in the Trans­form component.

In prin­ci­ple it is not so sim­ple to under­stand, but as we acquire prac­tice and study a lit­tle pro­gram­ming will become some­thing trivial.

Fig­ures 43 and 44 show two tests of the game in which the play­er appears in dif­fer­ent positions.

Fig. 43: The char­ac­ter appears in the door in the upper left corner.

Fig. 44: The char­ac­ter appears in the door in the low­er right corner.

Modularization

These four instruc­tions that we have cre­at­ed place the char­ac­ter in one of the doors randomly.

It would be great if we had an instruc­tion called "placeChar­ac­terI­nARan­dom­Door" and do all the work. Then we could put a sin­gle instruc­tion into start instead of four.

Luck­i­ly we can do exact­ly this by defin­ing a new method.

script c# genérico en unity 3d, método que se encarga de colocar el prefab aletoriamente
Fig. 45: A pri­vate method called "pla­ce­Play­er­Ran­dom­ly" is defined that does not require para­me­ters and does not return parameters.

The method will be called "pla­ce­Play­er­Ran­dom­ly", will not require para­me­ters, will not return data, and will be pri­vate. The def­i­n­i­tion of a method with all the enun­ci­at­ed char­ac­ter­is­tics is illus­trat­ed in fig­ure 45.

In the first two videos of this series I used Span­ish names, but I think it's bet­ter to get used to using Eng­lish names, as well as mak­ing it eas­i­er for me to translate.

script c# genérico en unity 3d, método que se encarga de colocar el prefab aletoriamente
Fig. 46: Move the four instruc­tions to the pla­ce­Play­er­Ran­dom­ly method.

We are going to select the four instruc­tions that we put in the Start method, we are going to cut them and paste them in this new method, as can be seen in fig­ure 46.

Then in the Start method we make the call to the pla­ce­Play­er­Ran­dom­ly method, as we see in fig­ure 47.

script c# genérico en unity 3d, método que se encarga de colocar el prefab aletoriamente
Fig. 47: We call pla­ce­Play­er­Ran­dom­ly in the Start method.

Reset Scene

To eas­i­ly test the ran­dom posi­tion fea­ture, I'm going to restart the scene by press­ing the R key.

For this we need to add the Name­space UnityEngine.SceneManagement, a Name­space is sim­ply a col­lec­tion of class­es grouped under a name, in this case they are relat­ed to the man­age­ment of scenes in Unity.

We added the Name­space in line 4 shown in fig­ure 48.

script c# genérico en unity 3d. definir variables y métodos. scenemanagement
Fig. 48: We import the Scene­M­an­age­ment library.

To read the key­board we use an if sen­tence and the Input class. Video 1 of the Uni­ty Fun­da­men­tal Series is about read­ing the key­board and mouse inputs, in the video arti­cle the infor­ma­tion is deepened.

Inside the sen­tence if we exe­cute the sta­t­ic method Load­Scene of the class Scene­M­an­ag­er and we pass as para­me­ter the num­ber zero, indi­cat­ing that the scene 0 is loaded. This scene would be the first scene declared in the win­dow Build Set­tings. In our case we only have one scene so it will just restart.

script c# genérico en unity 3d. definir variables y métodos. loadscene
Fig. 49: In the Update method we read the R key and if it is pressed we load scene 0.

Final details

The last thing we'll do is mod­i­fy the rota­tion of the Emp­ty GameOb­jects Spawn­Point, so that the blue arrow point­ing in the direc­tion oppo­site the door.

With the E key we select the rota­tion tool and keep­ing the SHIFT key pressed we make that the mod­i­fi­ca­tions of the angle are with fixed step, if I am not mis­tak­en of 15 degrees. That way if the Y axis angle is for exam­ple 0 degrees, we can take it exact­ly to 90 degrees thanks to that fixed step.

Fig. 50: Rota­tion of the appear­ance points so that the char­ac­ter appears as if there was an entrance through the door.

Fig. 51: In this case the blue axis indi­cates the direc­tion in which the char­ac­ter is look­ing. In this case it must be rotat­ed 90 degrees clockwise.

To con­clude we make a com­pi­la­tion. In the fig­ures 53 and 54 there are two dif­fer­ent starts of the game, in each one the play­er appears in a dif­fer­ent door.

colocar prefab aleatoriamente. el personaje aparece en una de las puertas
Fig. 53: Com­pi­la­tion test 1.

colocar prefab aleatoriamente. el personaje aparece en una de las puertas
Fig. 54: Com­pi­la­tion test 2.

Conclusion

In this arti­cle we saw how to cre­ate the first C# Script that will place the char­ac­ter in a ran­dom posi­tion on the stage.

All the attrib­ut­es were ana­lyzed to meet the objec­tive and it was explained what each one was used for.

Mod­u­lar­iza­tion is a use­ful tool to orga­nize our code and make it more intuitive.

Scroll to Top
Secured By miniOrange