#10 Place collectables on Unity randomly.

IMPORTANT UPDATE

I WILL PUBLISH THE FILES OF THIS PROJECT WHEN THE CHANNEL REACHES 1000 SUBSCRIBERS

…

I LEAVE AN UPDATED BUILD FOR YOU TO TRY, IT MAY TAKE A LITTLE WHILE TO LOAD
ūüĒĽ

MOVEMENT: WASD CAMERA LOOK: MOUSE

FROM HERE THE ORIGINAL ARTICLE CONTINUES

Introduction

In this arti­cle we are going to see a way to place col­lec­table objects in Uni­ty, these objects will be watch­es that when col­lect­ing them will add time in the countdown.

We are going to use the pre­fab­ri­cat­ed clock that we con­fig­ured in the sec­ond arti­cle of the project, click here to down­load the files and see how to con­fig­ure the pre­fabs.

Go to the project's Main Page

Before we begin I invite you to watch the video on which this arti¬≠cle is based. 

ACTIVATE and DEACTIVATE GameObjects through CODE in UNITY
ūüüĘ

PLEASE SUBSCRIBE

CHECK OUT THIS CRAZY EXPERIMENT

Objective description

We must estab­lish rules and make an exhaus­tive descrip­tion of the behav­ior of the clocks, for exam­ple how they will inter­act with the char­ac­ter, how they will appear on the stage, etc. The bet­ter the descrip­tion, the eas­i­er it will be to cre­ate a solu­tion using programming.

What we are look¬≠ing for is that a cer¬≠tain num¬≠ber of clocks appear in the labyrinth. We must make sure that these clocks do not appear inside the walls and do not over¬≠lap each other.

To achieve this I am going to reuse the solu¬≠tion from the pre¬≠vi¬≠ous arti¬≠cle to place the pedestal in a ran¬≠dom posi¬≠tion, in the solu¬≠tion I made each piece of the labyrinth know its own geom¬≠e¬≠try and give us a posi¬≠tion of its inte¬≠ri¬≠or if we ask for it.

reloj colocado aleatoriamente en unity
Fig. 1: The clocks will appear in ran­dom posi­tions in the labyrinth.

In addi¬≠tion, I am going to make sure that each piece of the labyrinth can con¬≠tain only one watch, in this way we do not run the risk of plac¬≠ing two super¬≠im¬≠posed watches. 

To achieve this we must keep a record of the pieces of the labyrinth that have a clock inside, so when we are going to place a new clock, those pieces will not be con­sid­ered in the selection.

When the char­ac­ter takes a watch, a cer­tain num­ber of sec­onds will be added to the countdown.

Every time a watch is destroyed, a new one appears on the stage, so that all the time we will have the same num¬≠ber of watch¬≠es on the stage.

Resolution

Previous steps

We start by select­ing GameOb­ject Con­trol from the hier­ar­chy and assign­ing it the tag "Game­Con­troller". Then select the GameOb­ject FPSCon­troller and assign the tag Player.

asignacion de tags en unity desde la ventana inspector
Fig. 2: Select the con­trol object and assign the tag "Game­Con­troller".

asignacion de tags en unity desde la ventana inspector
Fig. 3: Select the player's pre­fab and assign the tag "Play­er".

Next we are going to cre¬≠ate a new Script called Clock, which we will lat¬≠er assign to the pre¬≠fab¬≠ri¬≠cat¬≠ed clock.

creacion de scripts c# en unity
Fig. 4: We cre­ate a new script with the name "Clock".

This script will mod­el the behav­ior of clocks.

Fields of Clock Script

We are going to define a seri­al­ized String that we will call "play­erTag", this vari­able will con­tain sim­ply the name of the tag that we have assigned in the player.

Then we will define a float type vari¬≠able to indi¬≠cate the life time in sec¬≠onds of the clock on the stage.

We define a GameOb¬≠ject called labyrinth¬≠Piece with "get" and "set" as shown in Fig¬≠ure 5, this way it will be a para¬≠me¬≠ter that can be read and writ¬≠ten. I usu¬≠al¬≠ly like to define pub¬≠lic meth¬≠ods to access vari¬≠ables, but this is a very prac¬≠ti¬≠cal way to do it.

Final­ly we define a Game­Con­trol type object because the clock needs to inform the con­trol what is happening.

script c# en unity para controlar la aparicion aleatoria de relojes en el escenario
Fig. 5: We define these fields for use in the solution.

Methods of Clock Script

First we define the SetLife¬≠Time pub¬≠lic method with float para¬≠me¬≠ter that we will use so that the Game¬≠Con¬≠trol object assigns a cer¬≠tain life time to the clock.

Then there's the Self¬≠De¬≠struc¬≠tion method that will run when the clock's life time runs out or the char¬≠ac¬≠ter grabs it.

The Col­lect method will run when the char­ac­ter picks up the clock, alerts Game­Con­trol and then self-destruct.

Final­ly the OnTrig­ger­Enter method to detect the char­ac­ter, when this hap­pens we will exe­cute the Col­lect method.

script c# en unity para controlar la aparicion aleatoria de relojes en el escenario
Fig. 6: We define these meth­ods to use in the solution,

Fields in GameControl Script

Let's go to the Game­Con­trol Script and define four seri­al­ized fields.

Clock¬≠Pre¬≠fab will con¬≠tain the pre¬≠fab of the clock that we will place on the stage. The nClocks inte¬≠ger will indi¬≠cate how many clocks should be placed on the stage. The float clock¬≠Life¬≠time will be the aver¬≠age life¬≠time of a clock on the stage. Final¬≠ly the whole timePer¬≠Clock will indi¬≠cate how many sec¬≠onds are added to the Timer after the char¬≠ac¬≠ter takes a clock.

campos de la clase gamecontrol que se usaran para resolver el problema
Fig. 7: In Game­Con­trol we are going to define some fields to solve the problem.

GameControl Script Methods Statement

The PlaceAllThe¬≠Clocks method will make sure that it is pos¬≠si¬≠ble to set the indi¬≠cat¬≠ed num¬≠ber of clocks and then run the PlaceA¬≠Clock method as many times as clocks need to be set.

Clock­De­stroyed will be exe­cut­ed by a clock that has just self-destruct, that way the Game­Con­trol Script will be able to re-con­sid­er the maze piece where the clock was and place a new clock in a ran­dom position.

Clock¬≠Col¬≠lect¬≠ed will be exe¬≠cut¬≠ed by a clock when the char¬≠ac¬≠ter comes into con¬≠tact with it, this way we can add time to the timer.

Final¬≠ly, the Destroy¬≠All method will destroy every¬≠thing that must be destroyed at the end of a game (pedestal, clocks, char¬≠ac¬≠ter, etc.).

metodos de la clase gamecontrol que se usaran para resolver el problema
Fig. 8: We define some meth­ods in GameControl.

Clock Method Instructions

To start in the Clock Start method we find the ref¬≠er¬≠ence of the Game¬≠Con¬≠trol object, then we invoke the self¬≠De¬≠struc¬≠tion method in a time that is the result of the sum of the life time of the clock with a ran¬≠dom val¬≠ue between 0 and 1. In this way we achieve that the clocks are not destroyed in the same frame.

metodo start del reloj, encontrar referencias, invocar autodestruccion
Fig. 9: In the Clock Start method we are going to find the ref­er­ence of the Game­Con­trol com­po­nent and invoke self-destruction.

In the Self­De­struc­tion method, we inform the Game­Con­trol object that a clock has been destroyed and pass the maze piece assigned to the clock as a para­me­ter, so that the Game­Con­trol object can remove it from the exclu­sion list. Then we run the Destroy method with para­me­ter "gameOb­ject" so that the object destroys itself.

metodo auto destruccion del reloj
Fig. 10: In Self­De­struc­tion we are going to tell the Con­trol that the clock was destroyed and then run the Destroy method.

In the Col­lect method we are first going to can­cel the pend­ing invo­ca­tion of the self­De­struc­tion method. Then we inform the Game­Con­trol object that a clock was col­lect­ed. Final­ly we run the self­De­struc­tion method.

metodo collect para un reloj que aparece en el escenario aleatoriamente
Fig. 11: The Col­lect method informs the event con­trol and then self-destruct.

In the OnTrig­ger­Enter method we are going to ask if the tag of the Col­lid­er that touched the clock is the one of the play­er and if this is true we are going to exe­cute the Col­lect method.

metodo ontriggerenter para un reloj que aparece en el escenario aleatoriamente
Fig. 12: If the Col­lid­er that comes into con­tact with the clock has the tag "Play­er" we will exe­cute the Col­lect method.

GameControl Methods Instructions

PlaceAllTheClocks Methods

In the PlaceAllThe¬≠Clocks method of Game¬≠Con¬≠trol we will read the amount of labyrinth pieces we have avail¬≠able to place the clocks. If it turns out that more clocks must be placed than the num¬≠ber of labyrinth pieces, let's make nClocks equal to the num¬≠ber of labyrinth pieces minus one, this way we'll pre¬≠vent the pro¬≠gram from enter¬≠ing into an infi¬≠nite loop.

Then we will do a loop exe¬≠cut¬≠ing the PlaceA¬≠Clock method to place a clock on the stage.

metodo place all the clocks para colocar todos los relojes aleatoriamente en el escenario
Fig. 13: In the PlaceAllThe¬≠Clocks method we will put all the clocks on the stage.

StartGame Method

In the StartGame method we are going to cre¬≠ate the GameOb¬≠jects List object (line 182 of fig¬≠ure 14).

To cre¬≠ate the object is very impor¬≠tant, so much so that in a com¬≠put¬≠er exam in which it was nec¬≠es¬≠sary to write code on paper, I for¬≠got to place the new instruc¬≠tion to cre¬≠ate the object and I sub¬≠tract¬≠ed almost 40 points from 100. When I went to defend my exam they con¬≠sid¬≠ered that they had exag¬≠ger¬≠at¬≠ed a lit¬≠tle giv¬≠en that it had been my only error and they for¬≠gave me.

metodo start de gamecontrol, juego del laberinto en unity
Fig. 14: In Game­Con­trol Start we cre­ate the list object and then exe­cute the PlaceAllThe­Clocks method.

PlaceAClock Method

Return­ing to the sub­ject of meth­ods, in PlaceA­Clock we have to ran­dom­ly choose a piece from the labyrinth assur­ing us that the piece no longer con­tains a clock, once we get it, we ask for a ran­dom posi­tion of its inte­ri­or. To solve this it is nec­es­sary to have solved the exer­cise of the pre­vi­ous arti­cle, in which we cre­at­ed the Script Labyrinth Piece.

The algo¬≠rithm for plac¬≠ing the watch part can be seen in fig¬≠ure 15.

metodo place a clock para colocar un reloj aleatoriamente en el escenario
Fig. 15: The PlaceA¬≠Clock method will choose a piece from the labyrinth and place the watch.

ClockDestroyed Method

In the Clock­De­stroyed method we are going to remove from the list the piece of the labyrinth that is passed to us as a para­me­ter and then exe­cute the PlaceA­Clock method to place a new clock in the scenario.

metodo clock destroyed de gamecontrol para informar que un reloj ha sido destruido
Fig. 16: In Clock Destroyed we removed the maze piece con¬≠tain¬≠ing the watch from the list and placed a new watch.

AddSeconds Method of Timer

We need to define a pub¬≠lic method with¬≠in Timer that allows us to add a num¬≠ber of sec¬≠onds to the timer.

At the end of the script we make the dec¬≠la¬≠ra¬≠tion of the AddSec¬≠onds method, we will com¬≠plete it at the end.

metodo add seconds de timer para agregar segundos a la cuenta regresiva
Fig. 17: In the Timer Script we are going to add a pub¬≠lic method to add sec¬≠onds to the timer.

Return­ing to the Game­Con­trol Script, in the Clock­Col­lect­ed method we make the call to the AddSec­onds method of timer, pass­ing as para­me­ter the whole timePerClock.

metodo clock collected de game control para informar que se ha recogido un reloj y se debe sumar segundos al timer
Fig. 18: In the Clock Col­lect­ed method we are going to add sec­onds to the countdown.

Now let's go to the EndGame method, where the Destroy lines are, let's run the Destroy¬≠All method and cut the two Destroy instruc¬≠tions that we had pre¬≠vi¬≠ous¬≠ly placed in oth¬≠er items.

metodo end game para realizar todas las acciones al finalizar una partida
Fig. 19: Let's go to the EndGame method, cut the destruc­tion instruc­tions and exe­cute the Destroy­All method.

We paste those two instruc¬≠tions into the Destroy¬≠All method and then find all the clocks on stage and destroy them using a fore¬≠ach loop.

metodo destroy all para destruir todo lo que sea necesario al finalizar una partida en el juego del laberinto
Fig. 20: In Destroy¬≠All we paste the pre¬≠vi¬≠ous¬≠ly cut instruc¬≠tions and remove all clocks from the stage.

Setup Clock Prefab

Now let's select the pre¬≠fab¬≠ri¬≠cat¬≠ed clock from the project fold¬≠er and drag it to the sce¬≠nario to set it up.

prefab de elemento colectable en unity, los relojes aparecen aleatoriamente en el escenario
Fig. 21: Select the pre¬≠fab of the clock.

We cre¬≠ate the Clock tag and assign it to the GameOb¬≠ject of the clock.

creacion de tags en unity
Fig. 22: We cre­at­ed a new Tag called Clock.

asignacion de tags en unity desde la ventana inspector
Fig. 23: We assign the Clock tag to the pre¬≠fab of the clock.

ventana inspector de un reloj que aparece en el escenario aleatoriamente en el juego del laberinto
Fig. 24: Clock with the assigned tag.

Then drag the Script Clock to its com¬≠po¬≠nents or use the Add¬≠Com¬≠po¬≠nent but¬≠ton. Then we intro¬≠duce "Play¬≠er" in the tag field (fig¬≠ure 25).

gameobject colectable en unity
Fig. 25: Assign the Script Clock to the pre­fab of the clock and enter the player's Tag.

Let's go to GameOb­ject Con­trol and enter the new para­me­ters that we had pre­vi­ous­ly defined.

ventana inspector del game object control que se encarga de control el juego del laberinto, parametros para colocar elementos colectables en unity
Fig. 26: Select the Con­trol object and set the new para­me­ters in the inspector.

Now let's com­plete the AddSec­onds method of the Timer Script that we had pending.

Inside we will sim­ply increase the sec­onds, adjust the min­utes and exe­cute the Write­Timer method to update the values.

metodo add seconds de timer para agregar segundos a la cuenta regresiva
Fig. 27: Back to the Timer Script and com­plete the AddSec­onds method.

Programming error

At this point an error appeared in the con­sole say­ing that there is no ver­sion of the PlaceA­Clock method that does not have parameters.

error visualizado en consola de unity
Fig. 28: An error occurs say­ing that there is no method def­i­n­i­tion that does not con­tain parameters.

I go to line 184 of the Game­Con­trol Script where the error appeared, in effect we see in fig­ure 29 that the exe­cu­tion of the PlaceA­Clock method is done with­out parameters.

correccion de bug en script game control del juego del laberinto en unity
Fig. 29: I go to the instruc­tion where the error is located.

I define the inte­ger nPieces with the val­ue of the amount of ele­ments in the labyrinth parts list and enter this inte­ger as a method parameter.

correccion de bug en script game control del juego del laberinto en unity
Fig. 30: I define an inte­ger with the num­ber of labyrinth pieces and pass it as para­me­ter to the method.

Bug correction

When I test the game, the clocks didn't seem to have appeared on the stage. When I paused the sim¬≠u¬≠la¬≠tion and searched the hier¬≠ar¬≠chy, I dis¬≠cov¬≠ered that they had appeared but were upside down, as shown in fig¬≠ure 31.

bug en el que los elementos colectables en unity aparecen mirando boca abajo en el juego del laberinto
Fig. 31: When run¬≠ning the game we find a bug, the clocks appear face down.

To cor¬≠rect this bug I go to the method where a clock is placed on the stage and I look for the instruc¬≠tion in which I make the Instan¬≠ti¬≠ate, instruc¬≠tion 173 in fig¬≠ure 32.

Instead of giv­ing the new GameOb­ject the rota­tion of the Quater­nion iden­ti­ty I'm going to give it the rota­tion that is defined in the pre­fab of the clock, which when placed on the stage appears cor­rect­ly oriented.

solucion del bug en el que los relojes aparecen mirando boca abajo en el juego del laberinto
Fig. 32: I go to the point where I place the clocks on the stage.

solucion del bug en el que los relojes aparecen mirando boca abajo en el juego del laberinto
Fig. 33: Instead of using Quaternion.Identity I use the rota­tion defined in Prefab.

Final Details and Test

When I tried the game, I noticed that there were few watch¬≠es and that they gave up very lit¬≠tle time when I picked them up.

In order to bal¬≠ance the ele¬≠ments cor¬≠rect¬≠ly it is nec¬≠es¬≠sary to make sev¬≠er¬≠al tests and see what works best, in addi¬≠tion this can form part of a sys¬≠tem of dif¬≠fi¬≠cul¬≠ty in which a high dif¬≠fi¬≠cul¬≠ty implies less fre¬≠quent clocks that deliv¬≠er lit¬≠tle time when pick¬≠ing them up.

ventana inspector del game object control que se encarga de control el juego del laberinto, parametros para colocar elementos colectables en unity
Fig. 34: I adjust the val¬≠ues in Game¬≠Con¬≠trol to give me more time to col¬≠lect them.

In fig­ure 35 we have two clocks in front of nos­tors and the timer marks approx­i­mate­ly one minute fifty, the fig­ure 36 was tak­en moments after grab­bing the two watch­es, we see that the Timer now marks a lit­tle more than two min­utes ten. This con­cludes the problem.

escena del juego del laberinto en el que hay dos relojes para recoger y obtener tiempo
Fig. 35: In the scene two clocks are observed in front of the char­ac­ter and the time indi­cates 1:47.

escena del juego del laberinto
Fig. 36: After pick­ing up both watch­es, the time is 2:13.

Conclusion

In this arti­cle we have seen how to ran­dom­ly place col­lec­tables in Uni­ty, these col­lec­tables were the clocks that when col­lect­ing them had to add time to the countdown.

The object Game­Con­trol is in charge of plac­ing them on the stage ran­dom­ly using the solu­tion cre­at­ed in the pre­vi­ous arti­cle to place the pedestal ran­dom­ly in a piece of the labyrinth.

To solve the prob¬≠lem we have cre¬≠at¬≠ed a Script that will mod¬≠el the behav¬≠ior of the clock and will exchange mes¬≠sages with oth¬≠er Scripts to report events such as a self-destruc¬≠tion or that the char¬≠ac¬≠ter has picked up the clock.

The effect of col¬≠lec¬≠table ele¬≠ment we do it sim¬≠ply exe¬≠cut¬≠ing appro¬≠pri¬≠ate actions when the char¬≠ac¬≠ter pass¬≠es over them.

YouTube
Scroll to Top
Secured By miniOrange