Getting Started with Unity - GUI, Scoring, Timers & Particles

In this tutorial we'll introduce scoring with and more complex gameplay with a variety of different pickups to collect, some hindering the player and some providing speed boosts.

We'll also introduce a countdown Timer complete with a HUD displaying both the score and time remaining, as well as adding everyone's favourite feature - particles!


Step 1: Creating Different Pickups

Our mini game is going to have several different types of pickups for the user to collect. Type 1 will simply increment the score, type 2 will add or subtract a random score and type 3 will either speed up or slow down the player. To make it more interesting the pickups will randomly change while the player is playing.

The first step is to create a new script that will define what type of pickup each instance is.


Step 2: The Pickup.js Script

Open your project from last time or download the source from above; then within the Project Window right-click on the Scripts folder and select Create -> JavaScript; rename it Pickup.

unity tutorial: gui, timers, particles

We'll now add this new script as a Component of our pickup prefab, so select the 'pickup-prefab' from within the Prefabs folder and drag the Pickup script onto the Inspector Window (or onto the 'pickup-prefab' itself).

unity tutorial: gui, timers, particles

Every instance of the pickup that's now spawned will feature this new script which will determine the type of pickup it is and various other properties. Let's now define these types.


Step 3: Determining the Type of Pickup

When the pickup is spawned we're going to decide randomly what type it is, so add the following code to the Pickup script:

The above block of code defines a variable 'type' which, when the script initialises, is randomly set to a value of 1 (standard point pickup), 2 (point gamble pickup) or 3 (speed powerup) to define the type of the pickup.

We generate the random number using Random.Range(...) and then use a series of if statements to increase the probability of it being a standard point pickup (type = 1) and therefore make the speed powerups more rare to come across.


Step 4: Randomly Changing the Pickup

Once instantiated the pickup will currently remain the same type for the duration of its lifetime. Let's make it a little more interesting by making it change type after a random number of seconds.

Add the following variables and Start() function to the script:

This essentially starts a while loop which will run forever since the condition being tested is always true. The first part of the statement uses a yield WaitForSeconds(...) statement to create a delay for a random number of seconds, between the min and max values specified, before then swapping the type of the pickup by calling the SwapType function we defined earlier on.

So the game should currently work as we expect - but the player has no idea what type of pickup they are collecting! So now let's brighten up our pickup a little to distinguish between the different types. We'll use everyone's favourite feature...


Step 5: Everyone's Favourite: Particles!

So that the player can tell the difference between the pickups, we're going to add different coloured particle systems in the centre of the pickups.

Drag an instance of the pickup-prefab into the scene and focus on it by either using the F key or double-clicking on it within the Hierarchy. Add a Particle System using the top menu: GameObject -> Create Other -> Particle System. Make it a child of the pickup-prefab by dragging it onto the pickup-prefab within the Hierarchy; click Continue when the below dialog warns you about losing the prefab connection.

unity tutorial: gui, timers, particles

Use the Inspector to position the Particle System at (0, 0, 0) so that it's in the centre of the pickup model as illustrated below.

Note: if you have the particle system or one of its parents selected then the particle system will emit particles within the Scene Window; it will otherwise cease emitting the particles until reselected.

unity tutorial: gui, timers, particles

So you should now have your first particle system positioned in the centre of the pickup.

Particle Systems within Unity are made up of three Components: an Emitter, an Animator and a Renderer. Their names are quite self explanatory and each features a handful of public variables for you to customise, allowing all kinds of awesome visual effects to be produced.

You can read more about each on their Component Reference pages that are linked above. You can also find their Script Reference pages here: Emitter, Animator and Renderer.

Currently our particle system is quite boring, right? Select the particle system and within the Inspector adjust the Emitter Component to match the values below:

unity tutorial: gui, timers, particles

All we've done is alter the energy that the particles have, affecting how long they 'live' for, and shrunk the Ellipsoid where they are emitted from so you should now notice that the particles are now all emitted much more closely together in the centre of the pickup.

unity tutorial: gui, timers, particles

Now match your particle's Animator Component to the values shown below:

unity tutorial: gui, timers, particles

The changes we've made here are the addition of a random force to the particles on each axis, to make them appear more natural, and a size grow value of 1 so that they'll grow larger over time as shown below.

unity tutorial: gui, timers, particles

That's our particle system complete; we'll adjust the colours using our Pickup script.

Finally, to update the pickup prefab, with the pickup-prefab object within the hierarchy selected, click the Apply button at the top of the Inspector. You can then delete the pickup from the Hierarchy.

Let's now adjust our Pickup script to alter the colour of the particles depending on what type of pickup it is.


Step 6: Particle Colours

As you may have noticed within the particle systems Animator Component a particle can animate through five different colours, each of which may have a colour and alpha (transparency) value.

If you inspect the Script Reference page for the Particle Animator and take a closer look at the colorAnimation property you'll notice that it's an Array of Color Objects.

Let's now introduce a variable to store the pickup's particle system so we can access its colours, and introduce three new Arrays (datatyped to Color) to our Pickup script. Go ahead and add the following code to the script:

Save the script and reselect the pickup-prefab within the Project Window. Expand the pickup-prefab to view its children and drag the particle system which is a child onto the Pickup Components new particles variable.

You should also now notice the three new arrays within the inspector; set each of their sizes to 5 as below since this is how many colours the particles need to animate through.

unity tutorial: gui, timers, particles

The colours are all currently black, which isn't so exciting, so select the first element of Type1 and within the resulting colour palette select a bright colour (I used green below) and set the alpha (A) to 50.

unity tutorial: gui, timers, particles

Repeat this for the remaining colours of Type 1, increasing the alpha to full value and then back out again so the particles fade in and out - the alpha value for each colour is represented by the white bar along the bottom of the colour as shown above. I also chose to use a slightly darker green for when the particle is fading out - you can of course colour them however you wish.

Repeat this process using different colours for Type2 and Type3 as I have below.

unity tutorial: gui, timers, particles

 

So, that's our colours created. The last thing to do is to actually assign them to the colorAnimation property of the particle system's Animator.

It's worth noting, as mentioned in the colorAnimation Script Reference, that when modifying the colours via code you must grab, modify and re-assign the whole array rather than individual colours. We can thankfully just overwrite the current colorAnimation Arrays with our own ones, which is nice and easy.


Step 7: Assigning Particle Colours at Runtime

Introduce the following variable and overwrite the current Awake() function with the one below, which retrieves and stores the particles ParticleAnimator Component for us to use later on.

Finally, overwrite the current SwapType() function with the below:

This introduces an extra line for each condition of the if statement, assigning the relevant array to the colorAnimation property of the particleAnimator variable. Job done.

If you now play the game the powerups will each have coloured particles within them and there should be more with the colour used for Type1 than Type2 or Type3. They do still look a little boring, however, since they're just static on the spot; let's quickly add a little random rotation to them.


Step 8: Randomly Spinning Pickups

This is a dead simple addition, but it will make our pickups look a little more interesting.

Add the following variables and Update() function to the Pickup script:

Then, overwrite the Awake() function with the following, which calculates the random rotationSpeed when the script initializes:

If you now run the game again, the pickups should all rotate at random speeds! Time to start scoring!


Step 9: Deciding on Game Resolution

Before we construct our interface we have to decide on the resolution of our game and ensure our Game Window is of this resolution so we can accurately position our interface elements.

I'm using the default WebPlayer export sizes (600x450) which you can change using the top menu, Edit -> Project Settings -> Player. You can also decide which version of the WebPlayer template you wish to use.

unity tutorial: gui, timers, particles

Once you've decided on the resolution of your game you need to set your Game Window to be of the same size, you can do this using the menu in the top left hand corner of the Game Window shown below

unity tutorial: gui, timers, particles

We can now accurately position our interface elements within the Game Window, it's important to remember to position interface elements whilst observing the Game window, NOT the Scene Window.

Lets now start making our interface...


Step 9: Introducing GUITextures

Before we start scripting for the scoring we'll construct the interface to hold the score by introducing GUITextures (GUI = Graphical User Interface), which will form the static portion of the interface.

Download this package which contains the font and texture required for our interface. The Font used is called IrisUPC and is available here. Double-click the package to extract the contents and click Import to import all the assets when prompted with the Import dialog window:

unity tutorial: gui, timers, particles

You'll now have two new folders within your Project Window: Fonts and GUI.

Let's now start creating our game's GUI. First, add a new Empty GameObject (using the top menu), rename it to "GUI" and position it at (0, 0, 0). This will be the container for our GUI so our Hierarchy is neatly organised.

Expand the GUI folder within the Project Window and select the 'game-gui' and using the top menu add a GUITexture: GameObject -> Create Other -> GUITexture. You should now have something similar to below:

unity tutorial: gui, timers, particles

So, at the moment this isn't too great since we want to align this graphic with the top of the screen.

First, let's alter its pixel inset within the Inspector so that its pivot point is no longer in the centre, and then reposition it along the top of the screen. Select the game-gui and match its Transform and GUITexture Components to those shown below:

unity tutorial: gui, timers, particles

What we've done here is altered the GUITexture pixel inset Y value to -64 (which is the height of the image), so its pivot point is along the top of the image. Now when we set the Y value within the Transform Component to 1, the GUITexture aligns perfectly with the top of the screen; there would otherwise be a gap of 32px.

Remember: When positioning GUI Elements within Unity, (0,0) is the bottom left corner of the screen and (1,1) is the top right corner of the screen.

So that's it for our GUITexture; time to add the GUIText...


Step 10: Introducing GUIText

With the graphics for our interface in place it's now time to introduce GUIText which will display the player's score and the time remaining.

Expand the Fonts folder, select UPCIL within Iris, and then create a GUIText GameObject using the top menu: GameObject -> Create Other -> GUIText. Rename it to txt-score and make it a child of GUI.

You should now have some small text saying 'Gui Text' appear in the centre of the screen using the UPCIL font. Note: When creating GUIText it's easier to select the font before creating the GUIText than to set it afterwards.

Within the Inspector, match the Transform and GUIText Components' settings to those shown below:

unity tutorial: gui, timers, particles

The above Transform Component positioning will align the GUIText as shown below with the 600x450 WebPlayer resolution - if you are using a different resolution you may need to play with the values to align it correctly. Note that, by setting the Z axis value to 1, the GUIText gets positioned in front of the GUITexture.

We set the text to '888' since this is the widest it will ever be; we've also changed the anchoring to centre the text rather than having it aligned to the left. Finally we've enlarged the font size to 36:

unity tutorial: gui, timers, particles

Now follow the exact same steps again - but rename the GUIText to txt-time - and set its Transform Component to the settings shown below so that you have something similar to the image:

unity tutorial: gui, timers, particles

So that's the building of the interface complete, now it's time to hook it all together.


Step 11: Connecting the Score

Reopen the PickupController script and add the following two variables and function to the script:

Pretty self explanatory here. Two variables, one to track the score and one to store the textfield the score's displayed in. The UpdateScoreText() function sets the text of the textfield to the string value of the score variable using the ToString() function.

Before this function is called, however, we must assign our textfield a value. Add the following code to the Awake() function:

This will find the 'txt-score' GameObject - assuming you've placed it within your Hierarchy as asked - and retrieves its GUIText component. The score variable is then set to 0 and UpdateScoreText() is called.

Currently you should get a 0 on the screen when clicking Play; however there is nothing to increment the score, so replace the Collected(...) function with the one below:

You should notice we've added a few lines to the centre of the function to retrieve the type variable from the pickup that was collected and then increment the score by either a static value of 2 for pickups of type 1, or a random value between -2 and 5 for both type 2 and 3 pickups.

The textfield is then updated after the score is adjusted. Easy, right?

unity tutorial: gui, timers, particles

Before making the timer display lets make one of our pickups affect the player's speed.


Step 12: Speed Boosts!

Open the PlayerController script and add the following variables:

Now replace the current Awake() function with the following:

So what's changed? We've introduced a characterMotor variable which retrieves the CharacterMotor Component of the player where we can access the player's speed. We also introduced several speed variables to track the original speed and set minimum and maximum speed values.

This is all great so far, but it won't make a difference within our game since we're only storing the original speed. We need to adjust the speed when the player collides with one of the pickups.

Replace the OnControllerColliderHit(...) function with the below:

So we've added an extra if statement that tests whether the pickup type is equal to 3 which will then adjust the speed via the AdjustSpeed() function. Go ahead and add the AdjustSpeed() function below to the script:

The AdjustSpeed() function generates a random number, which is then used to decide whether to speed up or slow down the player. The function then waits for a time between 5 and 10 seconds before re-assigning the original speed. If you now play the game this should all appear to work correctly.

There is a problem, however.

If you collect a type 3 pickup and then collect another type 3 pickup before the original speed has been reset, then the function is still waiting and so the original speed will be reset far earlier than expected.

The approach we're going with use to solve this issue is by using StartCoroutine(...), passing the function name as the parameter, so we can later use StopCoroutine(...) which will remove the yield WaitForSeconds(...) statement within the function.

Replace the call to AdjustSpeed() within the if statement with the following code:

Now when you run the game it should function as expected if you can find two type 3 pickups in quick succession (if you've copied the above exactly they should be blue).


Step 13: The Countdown Timer

Creating a countdown timer within Unity is pretty simple! Create a new script called 'CountdownTimer' and add the following variables and Awake() function:

All pretty simple so far; we've declared a few variables and when the script initializes we're assigning the GUIText Component of the GameObject that the script is a Component of to the textfield variable.

We then make two function calls to UpdateTimerText() and TimerTick(). Let's start by adding the UpdateTimerText() function below to our script:

This is also pretty simple, converting the currentTime variable into a string and then updating the textfield with that string. Let's now add the timer functionality to our script with the TimerTick() function below:

So there's a little more going on in this function but it's still pretty simple; let's take a look...

We have a while loop which keeps looping until the seconds counter equals 0 - i.e. the game has ended. Within the loop we use the yield WaitForSeconds(...) statement to stop the script executing for 1 second. When the script begins executing again, the currentTime variable is reduced by 1 and the textfield is updated by calling UpdateTimerText().

Since it's a while loop, this flow is repeated until the currentTime equals 0, at which point the game is over and 'Game Over' is printed out to the console.

There is one final thing you need to do to make this work - and that is, of course, adding the CountdownTimer script as a Component of the 'txt-time' GameObject, since otherwise it's just an unused script in a folder!

Now run the game. The clock should tick down from 90 and stop at 0. (You will however be able to still run around afterwards but we'll remedy that in the next tutorial.)

unity tutorial: gui, timers, particles

Step 14: Conclusion

Hopefully you've enjoyed this latest Getting Started with Unity tutorial! We've covered GUITextures, GUIText, creating countdown timers and everyones favourite - Particles! In the next and final part of this series, we'll add an intro and ending screen for our game. See you there!

Tags:

Comments

Related Articles