As you know, Unity is my tool of choice for game development, due to its versatility, asset ecosystem and ability to port to different platforms.
For that reason, I’ve decided it’s a good idea to start a series of tutorials on Unity. In this installment, I will talk about how to create an infinite runner-style game. Before we continue, this tutorial requires some basic knowledge of PlayMaker to be followed. While this tutorial explains how things are made, you are expected to know what PlayMaker state machines are, how to add PM components, and how to add actions.
First of all, while I use Unity and PlayMaker to make this tutorial, if you are good at coding you should be able to reproduce this tutorial that way, since I won’t just be explaining how to build the PlayMaker components, but rather the logic behind everything. Also, note that I will be making a linear 3d runner, you can use the same logic for a sidescroller 2d runner, or a top down 2d runner.
Before anything else, you need to prepare the new project in the Unity version of your choice and then create what will be your basic “track” (ground) object. One thing to keep in mind is that you need exact measures for this to work correctly. For example, is your track object 10 units long, 100 units long, etc. For this exercise, I’ve crated this track object that is 100 units long.
Now, the first step is to make a test creator using PlayMaker. What we can do is make a “test creator” just to see that the basic idea is working: we will create a series of track objects one after another to see that they are placed correctly, and in sequence. There are two ways to work with PlayMaker. One of them is to have a “game manager” that has, literally, all the actions of the game; the other one is to add PlayMaker components to game objects as they are needed, and make them “talk” to each other via events. I like the second method better. While it is true it’s more difficult to keep track of multiple PlayMaker components in multiple game objects, I think a small PlayMaker network is easier to manage than a big network made of a lot of small ones.
Having said that, let’s configure our first PlayMaker component. The image below shows our basic creator. The “create_generic” state has two actions, “create object” and “next frame event”. In the “create object” action you see I’ve added “track_generic” as game object. This is my basic “track” object I created above. For the position (piece_position vector variable), I’ve created a vector variable with the values [0,0,0], which means this track object will be created at the scene’s origin. The “next frame event” makes the defined event to run at the following frame. The next state is called “counter” and this will count the amount of track objects we have created. We keep track of those track objects using an int variable (named “counter”) and an “int add” action: what we get is that, this action will addition a value of “1” every time this state. To prevent this from running infinitely (which would cause the computer to crash when it runs out of memory), I’ve added an “int compare” action that will fire up a “finishing” event after we’ve reached a maximum amount of tracks (in this case, three). Since we only have one track created (counter = 1) the event that will run is “next”, which corresponds to “less than” in the “int compare” action. Lastly, the third state is “next_position” which adds a value of [0,0,100] to our original “piece_position” vector variable. As you see, the amount added in Z is the same length of the track object (100). I’ve set the counter at “3”, but you can set it at any value that you want.
Please note that I could have left the first state (create_generic) without the “next frame event” action. I opt to do this to force it to wait one frame. I’ve found sometimes it is a good idea to do this, because sometimes actions will tend to run so fast your PM component reaches a maximum number of loops, which causes things to crash.
Our next step is to create our running avatar. Your avatar can be a cube, a sphere, or a character. In my case, I already have a character. What we will do is place the avatar at the scene origin and put an invisible plane below it, so it doesn’t fall. If you used a primitive (sphere, cube), it will already have a collider. If you used a character, add a collider to it. Then, you need it to move.
We can use two different methods to move our avatar. However, I find it better to use physic forces. That means we need a rigid body component. Add a rigid body component to your avatar and use the settings I’ve defined below. Note that I’ve checked the “freeze position” in X, as well as “freeze rotation” in X Y and Z. The reason I’m doing this is so that the avatar doesn’t slide to the sides as it moves, and doesn’t tip (fall to a side) while moving.
Now, add a PlayMaker component to your avatar and we will use this to make the avatar move forward. The image below shows the actions I added to this state machine. Just a note, you don’t really need to add the “get velocity” action. The only reason I added it was to check that the speed of the avatar was actually the speed I wanted it to have. Also, please note the “set velocity” action is set to run at every frame, since we need that speed to be kept during the entire game session.
Now, just hit play. The avatar should move across the tracks. It will eventually fall after it goes past the last track, but that is OK. In the next part, we will create a sequence that adds new tracks as they are needed.