Welcome to part six of this tutorial. Right now, we have a fully functional infinite runner game where you avoid obstacles.
You can leave it like this and just add a routine that keeps track of the traveled distance, and you’d have nice simple game. However, there are some variations that can be added to this.
First of all, let’s just get the “traveled distance” part out of the way.
Just add another FSM component to any object in your scene (since I already have a HUD, I add this FSM to one of my UI elements), and make this simple state machine. What this does is get your avatar’s Z position at every frame, so you know how many units your avatar has traveled.
If you wanted to be completely accurate, you could adjust this to real-world measures to get how many meters your avatar has traveled, but I think that’s just overkill. Besides, you just need to display a number next to a “distance traveled” text.
Now, we can create a routine that allows your avatar collect coins (or any other score-related item).
First, create another cube as a child of your avatar. This cube will be used to detect the coins. One thing you will notice is that I keep creating colliders as children of our avatar, instead of using the avatar’s collision. I do this because it helps keep things more organized. Right now we have a trigger that detects when a new track is needed, another one that detects when you’ve collided with an obstacle, and now, this last one will detect coins. Keeping separate triggers for our different needs is better than trying to fit everything in one single trigger.
Back on subject.
Turn that cube you just created into a trigger, and then add a new FSM component to it. Create a new tag, named “CueGeneric” and then create the following state machine. This state machine detects every time the trigger touches a coin, and then adds a value of 1 to the global score.
Note that the trigger detects objects with a specific tag. We need to use that tag for our coin.
Create a new cube object that we will use for our coin (you can use your own custom model if you want), and turn its collider into a trigger. Just like before, add a Rigid Body component to your cube, to make sure the avatar’s trigger detects it. Switch the cube’s tag to “CueGeneric” and then turn this cube into a Prefab.
Right now you just need to test it, so you can simply modify your spawner (pictured below as a reminder) to spawn this cue you just created instead.
If you press play, you will see your obstacles are now replaced with your coin prefab (I am using a custom 3d model). If you keep your PlayMaker editor open you will see the score increases by 1 every time you touch a coin.
Another thing you can do is randomize spawning elements. What I mean is, you can alter your routine a bit so it picks a random object (an obstacle, a group of obstacles, a coin) every time it spawns a new element. This can make your game more dynamic, since there are more things going on. That is actually what I’ve done for an infinite runner I’ve been working on.
And now for the last part, we need a HUD. First, create your basic UI with your Canvas, your Panel and two text fields. The first text field will be our score, and the second one will be our traveled distance. For the first field, we can create a routine that pulls the score value from our “coin detector” and then turns it into a string so it can be used as text for our UI.
For the second one, the traveled distance, I think it’s easier to simply delete the object we had previously created, and create the entire routine in the HUD element, as shown in the next image.
Now, if you try the game again, you will get updated score and distance values. Please note that I multiplied the score value by 100. That’s because scores in games look fancier when they have a few zeros next to them, than when they are single digit numbers.
Right now, you have a very rough prototype, though. It lacks music, visual effects, or nice graphics.
Some things you can do are add particles every time a coin is collected, and also particles as an “avatar destruction” event when it collides with an obstacle. It really depends on your own taste a game vision.
Next time I will show you how to add a few visual effects to make the game a bit better looking.