In this Unity Tutorial, learn how to make an Endless Runner or Infinite Runner game in 5 minutes! Or… at least the foundation for one.
There are many different approaches when it comes to the Endless Runner genre. Sometimes the player is stuck on a track and can only move in one axis, sometimes the player can freely move wherever they want while the camera scrolls. It depends on how you want to design it!
For this example, the camera will be stationary, the backgrounds will scroll across the camera and reset, and the player will only be able to move vertically within the confines of the camera to avoid incoming obstacles.
➤LIKE the video if you enjoyed, it really helps the channel!
➤MORE 5 Minute Tutorials: https://www.youtube.com/playlist?list=PLhrayuv80FeVbdfce8bQLwe-GxXf6LGtZ
➤Join our DISCORD SERVER: https://discord.gg/pMrMshh
We have channels to help you with your problems!
0:00 Repeating Background
The first thing we need to do is setup our repeatable scrolling background. I used an outer space theme as it’s just an easy way to accomplish this, but there are plenty of resources out there on how to make your own « seamless pattern » images.
Here is the 1.5 minute Photoshop tutorial I followed to make my space background: https://www.youtube.com/watch?v=pKs_5FkHjEc
My image was 2000×1000 pixels, which in Unity world space units is about 20 x, 10 y in our default Main Camera. This means that with my first image set to the origin position (0,0,0), a second image could be placed at (20,0,0) to be perfectly lined up.
Once you have a seamless pattern created and you’ve tested it by aligning 2 of them, we then want to add a BoxCollider2D, a Rigidbody2D, as well as a script to handle the scrolling & resetting position logic.
The BoxCollider2D will be used to store the width of the image, as adding a Collider2D defaults to auto-sizing the image (which is desireable in this case).
The Rigidbody2D will be used to move the background images across the screen.
The BackgroundScroller script will make all of that happen.
2:50 Player Controls
For my example, I’m restricting the player to only move up and down vertically. I used a 64×64 pixel square as the Player, set its sprite color to Cyan, added a Rigidbody2D component, as well as a new C# script PlayerController.
In PlayerController we get the Vertical Input axis value in our update, and setting our Rigidbody2D velocity we multiply the input axis by our movespeed.
Here are some other tutorials where I’ve covered player movement in more detail:
2D SideScroller Movement Tutorial: https://youtu.be/9HAZQROH2gM
2D Top Down Movement Tutorial: https://youtu.be/u8tot-X_RBI
6 Minute Pong Tutorial: https://youtu.be/YHSanceczXY
3:45 Bounds Detection
After setting up our player movement, the player is able to move outside of the bounds of the Main Camera. This is obviously not desirable (or is it?… you be the judge!), so we need to confine our player to stay within the camera’s view.
We could have the camera follow the player, but that breaks my design. Instead, I just added 2 new empty GameObjects, gave them BoxCollider2D objects, and using the tool in the Inspector, dragged the bounding box to be the length of the camera on the top and bottom edges.
4:02 Spawn Obstacles
Before we talk about spawning or instantiating any obstacles, we need to first make an obstacle to use! Reusing the same 64×64 pixel square as the Player, I scaled it up 5 in the x, and 5 in the y. I also colored it Red, and added a BoxCollider2D component with Is Trigger checked to True.
It’s important to add a tag to these Obstacles, so I created a new Tag called… well, « Obstacles » and assigned it. I then made sure there was an Obstacle GameObject nested under each Background GameObject.
To spawn these Obstacles, at the start of the game as well as every time a background image resets its position, I fetch the Obstacle GameObject by using the background’s transform’s GetChild method. I then simply set the Obstacle localPosition (important when working with nested GameObjects) to a new Y position between -3 and 3. I determined these values by dragging the obstacle in the editor to the top and bottom edges of the camera and rounding to the cleanest number.
I wanted to give a short demonstration of how it could be done, but I think here is where you will need to expand things in your own project to really make it… interesting.
4:44 Obstacles destroy Player
The last thing we need to do is modify our PlayerController script to make it so if a Player collides with one of these Obstacles, then the game ends. Using the tag setup in the previous step, within our OnTriggerEnter2D event, we can check the other gameObject’s tag if it’s « Obstacle » and if it is, Destroy the player.
4:54 You did it!
Way to go Lil Noober! If you struggled to get to here and have questions, leave a comment or join our discord and post in our problem-solving channel!
Source