The Infinite Runner is one of the staple game types in the mobile gaming genre of Hyper Casual. And with an understanding of 3 fairly simple steps, you can make your entry into the genre.
Here you can see the basic elements of an Infinite Runner using Unity Primitives. In this article, I will cover getting a project to this stage. From there, you will be able to add your own art assets and animations, as well as your own mechanics.
First, let’s look at the Player and the environment connected to them. the above example was made to make it clear that the ground is moving under the Player and not the other way around. In a full game, the ground would be spawned further off screen with additional side ‘scenery’ to help enforce the sense of player movement.
The Player Space is a group of objects that are stationary with relation to the Player. These include the Camera, Spawning/Despawning Locations and Triggers. In this case, I have also used Lane Marker Objects to ease movement between the Lanes and to serve for spawn points of effects if desired.
It is in the space that we will be moving the Player. To this end, I have set up an array to hold the Lane Markers, an int Current Lane and a Movement Enum. I’ve also decided to use the GetKeyDown to require individual inputs for the demo build. This could easily set up to work with mobile controls using buttons which we can explore in another article. I am also limiting the movement in the Demo to Left or Right, but by using the Enum and additional row of Lane markers, it can be expanded to allow Forward and Back movements.
Here I check for the Input in Update() and check that the Lane the Player is in isn’t the last in the direction the want to go. Then setting a Can Move bool, I insure that the move is completed before the Player can move again.
This is where the Move() co-routine come into play and serves as a pseudo Update Loop. I change the Player’s Current Lane and translate them towards it. Once the movement is completed, the Can Move bool is reset giving the Player back control.
I also have a Jump feature that uses the Player’s Rigidbody and a Raycast to check their position in relation to the surface they are running on. This insures the player can only jump when touching the ground or on top of an obstacle. No double jumps here.
It is the job of two scripts to manage the Spawning and Despawning of the moving platforms. Attached each to separate Game objects with collider, They detect the platform and preform the needed tasks. The first uses a Prefab and the Spawn Location GameObject to bring new platforms into existence. The second, placed so the when reached the platform is completely out of the Camera’s frame, destroys the platform. For a more performant result, you would want to set up a pool system for the Platforms instead of destroying and respawning them. Destroy is used here only for simplicity.
The next 2 steps involve the Platforms themselves. First, is their movement.
Since there is already Scripts taking care of Spawning and Despawning the Platform, it’s movement is as simple as Translating it along a route at a constant speed. I have a Speed variable, that can be adjusted by the designer or code, applying to Vector3.Back which causes the Platform to move towards the Camera along the Z axis.
Populating the Obstacles and Coins both work on similar principles and can be either setup to appear at random (as I have done) or pre-planned patterns.
Using multiple random numbers, I populate the Obstacles on the platform.
The most noteworthy item in this method is the unusual usage of the For loop. By pulling the i++ from the parameters, I can use it in the loop to control whether it advances. Here it is used when an Obstacle can be deactivated. This prevents the off chance of the same obstacle being picked twice from causing the Platform to have 2 Obstacles when it was meant to have just 1.
And lastly, taking a closer look at the Obstacle, we can see that I used two Box Colliders within it. The top Collider is used as a solid surface for the Rigidbody to land on and should not penalize the Player in any way. The large and lower Collider is set a trigger and serves the purpose of detecting interaction with the player. It triggers the Coin loss penalty in my Demo, but could as easily for any number of Penalty events in your game.
Now you know the basics on creating an Infinite Runner. This could be the next Temple Run or Subway Surfer. But in learning this, you have also learned how to make similar side scrolling games like Flappy Bird. The principles in the level movement are the same.
Now get out they and get creating.