So far, we’ve seen how to build an infinite track, an auto-running avatar, and a camera. However, there are other things we could do to this game, although some of them depend on what kind of runner you want to make.
One example could be a game where you must avoid obstacles, and another one could be a game where you must collect coins to increase your score. However, for both of these examples you need a wider track and the ability to move left and right (be it to collect those coins, or to avoid obstacles).
On the other hand, if you want to make a game where you have to collect colored coins with different buttons, you can stick to one track.
For this example, I will show you how to make a game where you must avoid obstacles. We can explore those other variations (collecting coins, or colored coins) after. The first thing you need to do is create a wider track model to replace the old one (or add the new one as an alternate option for a different game mode).
Then, you need to add the ability to move left and right. While I used “set velocity” to make the avatar move forward, I think a different method is better to make the avatar move left and right, since it will be more responsive.
What I mean by this is that, if you use the “set velocity” action, you will find yourself dealing with acceleration and deacceleration as a byproduct of this function, and that will only make the avatar harder to control. First, create another empty object as a child of your avatar and name it RayCastPoint, and then create the following FSM (please note that in the MoveSides state both Raycast actions are the same, except that the non-expanded one uses a direction of [-1,0,0]; also, the LeftSide and RightSide states are also the same, except that RightSide uses a direction of [1,0,0]).
The idea is this: You use the Get Axis action to get the value of your horizontal axis (it can be a joystick axis, or your arrow keys) and then uses that value to translate the avatar left or right. This simple thing could be enough but there’s an issue. The “translate” action ignores collisions so your avatar will actually go through the track’s side wall collision. To solve this issue, I added two raycast actions so they detect the left and right walls of the track and then send you to the corresponding state (LeftSide or RightSide).
The LeftSide and RightSide only detect half of the horizontal axis (the one opposite to the wall) using the Float Clamp option. When you “touch” either of the walls, your avatar will no longer move in that direction and the only available direction is the opposite. For example, in the LeftSide state, I clamp the result of the horizontal axis from 0 to 10, meaning the avatar is only able to move to the right (and thus preventing it from going through the track wall).
If you play play now, you’ll be able to move left and right as you run through the track.
For the obstacles, you will need to make them show up way ahead, so you have enough time to react. Right now, we will focus on a simple routine that will create one type of obstacle (that I already have).
The basic idea will be this: we will get the avatar’s world position in Z, and then add 100 units to Z (for example, if your avatar is at Z = 654, our resulting Z will be 754), and then use that new Z to set a vector point where an obstacle will be created (you don’t need to use exactly +100, you can use any value). First, create this simple state machine on either your avatar, or your track creator object.
First, this state machine waits for 3 seconds after the level starts, and then it moves to the next state that fires the spawn state. The important one is the last one. This one uses a “get position” action to get your avatar’s position, and then, with a “float add” action I add 100 to that Z value.
Then, I create a vector using the “set vector3 XYZ” action with 0 in X and Y, and my desired value in Z (the one that just got added 100 units). Then, with a “create object” I create my obstacle at that point, and then I use a “send event” to go back to the previous state. Now press play, and you will get a lot of obstacles (in my case, I am using assets of my current project).
Next time we will add some randomness to the obstacles, and also add a routine that destroys your avatar when you crash with an obstacle.