#7 Making the Countdown Timer in C# — Labyrinth Series

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 how to pro­gram a timer in C#, the oper­a­tion will be count­ing back­wards from the ini­tial val­ues of min­utes and sec­onds that we indi­cate and in addi­tion the Timer will be in charge of updat­ing the infor­ma­tion in the user inter­face cre­at­ed in the video 5 of the series of the labyrinth. Here is the arti­cle in which we cre­at­ed the user inter­face, in short we cre­at­ed some ele­ments for the Can­vas, which will allow the user to start play­ing and see infor­ma­tion about the game. 

Go to the project's Main Page

Before we begin, I invite you to watch the video of this article. 

CHECK OUT THIS CRAZY EXPERIMENT

Objective

The pro­to­type is a first-per­son game in which the stage is a maze. Inside the maze, there will be a hid­den object that must be found before time runs out.

Now we're about to solve the part where time runs out. In this arti­cle we'll cre­ate a script that is going to work as a count­down timer.

The Timer will start the count­down from a val­ue of min­utes and sec­onds that we will indi­cate in the inspec­tor, this means that every sec­ond of clock we must update the information.

The Script Timer will also mod­i­fy the val­ue of the Can­vas text ele­ment (top of fig­ure 1).

When the time count reach­es zero, the Script Timer will exe­cute the EndGame method of the Game­Con­trol Script, this way the game will end and we will return to the main menu.

escena en unity, en la parte superior un objeto texto que mostrara el valor del timer en c#
Fig. 1: The aim is to con­trol the text at the top so that it shows the remain­ing time.

Step by Step

We start by cre­at­ing the Timer Script and open it in the edi­tor. In order to access to the UI com­po­nents, like on-screen texts and but­tons, we need to include the UnityEngine.UI name­space at the top of the script (fig­ure 3).

nuevo script c# llamado timer en unity
Fig. 2: A new C# Script named Timer is created.

paquetes importados en el script timer
Fig. 3: Make sure you import UnityEngine.UI to access the user inter­face methods.

Fields

To make the count­down timer work we'll need a cou­ple variables.

In fig­ure 4 you can see a "[Seri­al­ize­Field]" instruc­tion above cer­tain vari­ables, this sim­ply makes the vari­ables and fields to appear in the inspector.

The two seri­al­ized inte­gers (min­utes and sec­onds) are the ini­tial val­ues of the count­down timer.

While the two pri­vate inte­gers (m and s) will be used to keep track of time.

campos definidos en script timer
Fig. 4: Fields to pro­gram the count­down timer's functionality.

We also need a Text type object to have the ref­er­ence of the Text com­po­nent of the Canvas.

Select the "Con­trol" object from the hier­ar­chy and assign the Timer Script. We see in the inspec­tor the seri­al­ized fields of the Script Timer: min­utes, sec­onds and timer­Text.

unity ventana inspector mostrando componentes de gameobjects
Fig. 5: Assign the Script Timer to the GameOb­ject Con­trol hierarchy.

jerarquia de un proyecto en unity
Fig. 6: Take the GameOb­ject Timer and take it to the Timer­Text field in the pre­vi­ous figure.

Let's write one minute and five sec­onds for the ini­tial val­ues of the count­down timer. Then take the Timer GameOb­ject from the hier­ar­chy (the one that con­tains the Text com­po­nent, fig­ure 6) and drag it to the timer­Text field.

unity ventana inspector mostrando componentes de gameobjects
Fig. 7: We write val­ues to ini­tial­ize the variables.

In fig­ure 7 we can see that in the timer­Text field a Text type com­po­nent has been recognized.

Methods to implement

Hav­ing in mind how a Count­down timer works, some ideas of pos­si­ble meth­ods emerge. First for the Timer to start work­ing we'll cre­ate a method called Start­Timer(). Then anoth­er method that runs at inter­vals of a sec­ond that is going to take care of incre­ment­ing the time val­ue, we'll call it Update­Timer(). A third method to stop the Timer, that will be exe­cut­ed when it fin­ish­es count­ing, this will be StopTimer().

script c# para resolver el funcionamiento de la cuenta regresiva
Fig. 8: We remove the Update method and cre­ate new meth­ods to solve the problem.

Final­ly, a method that mod­i­fies what is being shown in the user inter­face, this method will be called Write­Timer() and will take as para­me­ters two inte­gers for the min­utes and seconds.

metodo en c# para escribir un timer
Fig. 9: We also added a method to write the Timer.

Note that the para­me­ters required by this method have exact­ly the same name as the two inte­gers pre­vi­ous­ly defined, which are in charge of keep­ing track of the time. 

This is done so on pur­pose to talk a lit­tle about con­texts in pro­gram­ming, prob­a­bly for lat­er in anoth­er article.

Programming the functions of the countdown timer

UpdateTimer() Method

We have pro­posed some meth­ods intu­itive­ly con­sid­er­ing rough­ly the func­tion­ing of the Timer, now we must fill those meth­ods with C# instruc­tions that are the ones that will do the job.

The Update­Timer method will take care of sub­tract­ing a sec­ond, check­ing if the time has not run out, and mod­i­fy­ing the min­utes accord­ing­ly. Final­ly, it will use the Write­Timer method, pass­ing you the val­ues of min­utes and sec­onds. Fig­ure 10 shows an exam­ple of how to imple­ment this.

seria de instrucciones en c# para refrescar el valor de un timer
Fig. 10: Instruc­tions for the Update­Timer method.

In the first instruc­tion of the method we decrease by one unit the vari­able sec­onds, then we check if this vari­able is neg­a­tive, i.e. if pre­vi­ous­ly it was worth 0 and now it is worth ‑1.

If this hap­pens we notice if the min­utes vari­able is worth 0, if it is true this means that the time of the Timer is exhaust­ed (I leave the com­ment //endGame in that region). If the min­utes are not equal to zero, we decrease the min­utes vari­able by one unit and make the sec­onds vari­able worth 59.

Final­ly we exe­cute the Write­Timer method pass­ing the vari­ables m and s as parameters.

WriteTimer() Method

This method will take care of mod­i­fy­ing the Text object that we had defined. Depend­ing on whether the vari­able has a sin­gle dig­it (i.e. less than 10) or has two dig­its (greater than or equal to 10), we are going to exe­cute the instruc­tions seen in fig­ure 11.

What is done is to con­cate­nate a series of strings or text strings, in the case that s is less than 10, we con­cate­nate a 0 in front of the sec­onds so that it con­serves the for­mat of two numbers.

There are oth­er ways to do this such as set­ting a for­mat for text strings, but in this way we take the oppor­tu­ni­ty to see how eas­i­ly we can con­cate­nate text using the sum operator.

seria de instrucciones en c# para refrescar el valor de un timer
Fig. 11: Instruc­tions for the Write­Timer method.

StartTimer() Method

This method will per­form the ini­tial­iza­tion of the Timer, that is, we take the min­utes and sec­onds vari­ables that appeared in the inspec­tor with the ini­tial val­ues and assign them to the vari­ables m and s that car­ry the count. 

The method to write the val­ues in the graph­i­cal inter­face is executed.

Final­ly we use the Invoke method, giv­ing as para­me­ters the string "update­Timer", which is the name of the method and the sec­ond para­me­ter is 1f that rep­re­sents a sec­ond. This will make the update­Timer method run after one second.

seria de instrucciones en c# para iniciar un timer
Fig. 12: Instruc­tions for the Start­Timer method. Invo­ca­tion of updateTimer.

We are going to add this same instruc­tion at the end of the update­Timer method, this way the method will invoke itself every sec­ond. This can also be done using the Invok­eRe­peat­ing method instead of Invoke.

seria de instrucciones en c# para refrescar el valor de un timer
Fig. 13: The update­Timer method invokes itself every second.

Interactions between Scripts

The Timer is like a device that ful­fills its func­tion, we can con­fig­ure it, put it to run and stop it. With this in mind, we are going to make the Game­Con­trol Script the one that con­trols the Timer, being able to start and stop it using its pub­lic methods.

If you wan­na read more about exe­cut­ing func­tions from oth­er Scripts you can check this arti­cle.

First we are going to define a Timer type object to use in the Game­Con­trol Script.

Then in the Start method we find the Timer ref­er­ence that is assigned to the same GameOb­ject Con­trol hier­ar­chy (hier­ar­chy in fig­ure 6). 

script para controlar el juego
Fig. 14: Add a Timer type object to the fields of the Game­Con­trol Script. Ref­er­ence is found in the Start method.

In fig­ure 14 we see under­lined, the state­ment of this object Timer and how we find the ref­er­ence in the Start method.

Now the Game­Con­trol Script has the ref­er­ence of the Script Timer instance, this means that you will be able to access its meth­ods and pub­lic fields using the dot operator.

In GameControl's StartGame method we're going to make the Timer start working. 

metodo start game del script que controla el juego
Fig. 15: In the startGame method we exe­cute the Timer start­Timer method.

At the same time, we also want the Timer to have some way of telling the Game­Con­trol Script that time is up, so we also need the ref­er­ence to the Game­Con­trol object with­in the Timer Script.

In fig­ure 16 we see the dec­la­ra­tion of this object and how the ref­er­ence is found with­in the Start method.

fragmento del timer en c#
Fig. 16: Add a Game­Con­trol type object in Timer and find the ref­er­ence in Start.

For now we are going to make that when the time runs out the game ends and we return to the main menu, that is to say the same thing that would hap­pen if we press the Escape key. This can be done by run­ning GameControl's EndGame method.

In pre­vi­ous videos we had declared it with pri­vate vis­i­bil­i­ty, which implies this method can not be exe­cut­ed from an exter­nal con­text, for exam­ple the Script Timer.

So that we can exe­cute it from the Timer Script we change to pub­lic vis­i­bil­i­ty. See fig­ures 17 and 18.

visibilidad privada de un metodo, no accesible desde otro contexto
Fig. 17: We observe that the vis­i­bil­i­ty of the EndGame method is pri­vate, that's why we can't exe­cute it from Timer.

visibilidad publica de un metodo, accesible desde otro contexto
Fig. 18: We change the vis­i­bil­i­ty to pub­lic so that it is acces­si­ble from anoth­er context.

Now if, in the Update­Timer region where we detect­ed that the account reach­es zero (we had left the //endGame com­ment), we exe­cute the EndGame method of the Game­Con­trol Script and then the return sen­tence to fin­ish the exe­cu­tion of the Update­Timer method.

programacion de un timer en c# utilizando invoke
Fig. 19: We iden­ti­fy the region of the code in which time has run out and exe­cute the EndGame method.

In the EndGame method of the Game­Con­trol Script we are going to stop the Timer, as can be seen in fig­ure 20.

Why didn't we make the Update­Timer method stop the Timer when the count reach­es zero?

It could have been done in many dif­fer­ent ways, at the time I chose to do so bear­ing in mind that the Timer only serves the func­tion of keep­ing track of time and warn when the time runs out, then the Game­Con­trol Script that uses the Timer decides what to do with it.

metodo c# unity que se encarga de detener el juego
Fig. 20: In the EndGame method we exe­cute the action to stop the Timer.

StopTimer() Method

In this method we will only can­cel all invo­ca­tions that may be pend­ing, we could also reset the timer val­ues to the ini­tial values.

As an obser­va­tion, in the code of fig­ure 19, if the Timer reach­es zero, the EndGame() method is exe­cut­ed and then the instruc­tion return, which means that the pro­gram is forced to exit the cur­rent method, there­fore update­Timer() will not be invoked again and the Can­celIn­voke() instruc­tion would not be necessary.

But we could exe­cute the EndGame method due to oth­er rea­sons, for exam­ple press­ing the Escape key or the play­er wins the game, in those cas­es it is nec­es­sary to can­cel the Update­Timer invocations.

metodo para detener un timer en c#
Fig. 21: In the Stop­Ti­mer method we can­cel invo­ca­tions that may be pending.

Final tests

I'm going to make sure it works as expect­ed, first I'm going to set 0 min­utes 5 sec­onds as ini­tial val­ues and enter the game mode.

unity ventana inspector mostrando componentes de gameobjects
Fig. 22: I set the ini­tial val­ues to quick­ly observe the results.

When enter­ing the game mode the Timer starts with 5 sec­onds, makes the count­down and when it reach­es 0 we see in fig­ure 24 that returns to the main menu.

escena en unity que funciona como menu principal, boton para empezar el juego
Fig. 23: We entered the game mode to test the oper­a­tion of the countdown.

escena en unity, en la parte superior un objeto texto que muestra el valor del timer en c#
Fig. 24: When the time runs out, the result is the same as press­ing the Escape key, the EndGame method is exe­cut­ed and we return to the main menu.

Now we ver­i­fy that the for­mat of two num­bers for sec­onds is respect­ed and that the min­utes are cor­rect­ly decre­ment­ed when the sec­onds go from zero to 59. We start the Timer with 10 min­utes 5 sec­onds and enter the game mode.

We observe that the for­mat of two dig­its is respect­ed for the sec­onds and in addi­tion the min­utes are decre­ment­ed cor­rect­ly. The exer­cise is finished.

escena en unity, en la parte superior un objeto texto que muestra el valor del timer en c#
Fig. 25: Test again with the timer in 10 min­utes 5 seconds. 
escena en unity, en la parte superior un objeto texto que muestra el valor del timer en c#
Fig. 26: The for­mat of the count­down is respected.

Conclusion

We have man­aged to com­plete our Timer in C#, which serves the func­tion of keep­ing track of time, dis­play­ing it in the user inter­face and when the time runs out noti­fy the Game­Con­trol Script to decide what to do.

This timer could have been imple­ment­ed in sev­er­al dif­fer­ent ways, the Invoke method was cho­sen in this case, because I con­sid­ered a quite sim­ple alternative.

We saw how eas­i­ly we can mod­i­fy a text com­po­nent of the Can­vas as long as we have its ref­er­ence, so we can use this for oth­er things like scor­ing, infor­ma­tion mes­sages, etc..

We began to intro­duce lit­tle by lit­tle the con­cept of objects, how each has a spe­cif­ic func­tion and have ref­er­ences to oth­er objects to make use of their meth­ods and pub­lic para­me­ters. This is an extreme­ly inter­est­ing and use­ful top­ic for cre­at­ing object-ori­ent­ed solutions.

YouTube
Scroll to Top
Secured By miniOrange