Categories
Sotfware & DevOps Tools & HowTo

Unity Game Development Engine: How to Create an Endless Runner Game

Creating a game has never been easier than now by using the Unity game development engine. Whether you want to play in a 2D, 3D, FPS Action, or Endless Runner, the Unity game development engine offers endless possibilities. 

Unity Game Development

Getting Started with Unity Game Development Engine

I started to create a game on the Unity engine on the weekends, calling it “The Weekend Gaming Project.” I wasn't playing games, but instead, I dedicated my free time to learning how to create a game with the Unity Game Development engine. 

The first project I tried to get the hang of Unity was a fairly basic Pong game, where I had two paddles and a ball. This project was simple because I wanted to test my newly gained knowledge practically.

Then, I decided to move on to the Endless Runner-type games, which were all the buzz. Don't believe me? Do you remember Temple Run, Subway Surfers, and Jetpack Joyride?

This article will cover the creative and coding processes that went into creating the game from scratch. We’ll look at the concept of the game, its features, and what was the entire process like. If you’re interested, keep reading, and you will find everything you need to know to start creating your own game with the Unity game development engine!

The Inspiration Behind an Endless Runner Game On Unity Game Development Engine

I wanted to make something like Jetpack Joyride, with its horizontals. That said, I still wanted it to be like Temple Run, where the obstacles come from the top of the screen to the bottom, with three lanes for the players to navigate through. This is where my game would be unique.

So, the development process wasn't always smooth for me; there were hiccups and things I needed to learn to handle correctly. However, with persistence and (a lot of) research, I could continue developing my Unity game.

The first piece of code that I worked on was the player movement. It was relatively easy in C# or C Sharp, the language used by the Unity game development engine, since I only had three lanes to move the character from. Here's a code snippet in C# for the Player that deals with this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Player : MonoBehaviour {

    public float speed;
    public float increment;
    public float maxY;
    public float minY;

    private Vector2 targetPos;

    public int health;

    public GameObject moveEffect;
    public Animator camAnim;
    public Text healthDisplay;

    public GameObject spawner;
    public GameObject restartDisplay;

    private void Update()
    {

        if (health <= 0) {
            spawner.SetActive(false);
            restartDisplay.SetActive(true);
            Destroy(gameObject);
        }

        healthDisplay.text = health.ToString();

        transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);

        if (Input.GetKeyDown(KeyCode.UpArrow) && transform.position.y < maxY) {
            camAnim.SetTrigger("shake");
            Instantiate(moveEffect, transform.position, Quaternion.identity);
            targetPos = new Vector2(transform.position.x, transform.position.y + increment);
        } else if (Input.GetKeyDown(KeyCode.DownArrow) && transform.position.y > minY) {
            camAnim.SetTrigger("shake");
            Instantiate(moveEffect, transform.position, Quaternion.identity);
            targetPos = new Vector2(transform.position.x, transform.position.y - increment);
        }
    }
}

To analyze the code a bit here are a few things to take notice:

  • maxY and minY: These parameters help contain the player movement in the vertical axis.
  • targetPos: This stores the target position of the player so that it calculates the new position.
  • movEffect: It's a prefab that adds visual effect when the player moves
  • camAnime: It references the Animator component that is used to trigger a camera shake when the player moves.

The Idea Behind the Main Character: A Ghost Protagonist

I wanted the game's protagonist to be a Ghost creature traveling through a dark tunnel facing obstacles that become progressively difficult. However, such a grim protagonist might repel a lot of people. So, I tried to make it as non-threatening as possible when I created the graphics for the main character and the enemies.

The Decision to Make an Endless Runner Unity Game

The decision to develop an endless runner game was easy for me since I wanted the players to test their skills. The game was projected to become progressively harder which meant the more someone played, the harder it would get. Also, the dynamics of an endless runner games makes it feel like no play through is the same as the previous one. Why? There are many variables in how and which obstacles show and what path the player will decide to take. This can lead to an array of possibilities.

What was a challenge for me was the spawner for the obstacles/enemies. I had no clear way to make it seem random and progressively feel more difficult. Here's what I came up with in C#:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Spawner : MonoBehaviour {

    private float timeBtwSpawns;
    public float startTimeBtwSpawns;
    public float timeDecrease;
    public float minTime;

    public GameObject[] obstacleTemplate;

    private void Start()
    {
        timeBtwSpawns = startTimeBtwSpawns;
    }

    private void Update()
    {
        if (timeBtwSpawns <= 0)
        {
            int rand = Random.Range(0, obstacleTemplate.Length);
            Instantiate(obstacleTemplate[rand], transform.position, Quaternion.identity);
            timeBtwSpawns = startTimeBtwSpawns;
            if (startTimeBtwSpawns > minTime) {
                startTimeBtwSpawns -= timeDecrease;
            }
        }
        else {
            timeBtwSpawns -= Time.deltaTime;
        }
    }

}

I decided to use different templates for spawning the enemies, and then the code can choose one of the templates randomly. Here are a few aspects of the code snippet above:

  • timeBtwSpawns: This variable refers to the time remaining until the next obstacle spawn.
  • startTimeBtwSpawns: This is the initial time between spawns.
  • timeDecrease: The amount of time that the time decreases when spawning.
  • minTime: This is put in place so that the timeBtwSpawns will not decrease below this level.

Boo: Inspiration for the Visuals and Graphics

I already had an idea in mind that I wanted a ghost-like character (think Hollow Knight), and I finally decided to draw a pixelated Casper character. However, my pixel art skills were not good enough, so I did this model instead. 

Ghost Game Character Adobe Photoshop

I know! It looks nothing like Casper, so I decided to name it Ghostly instead, which ended up being the name of the game in the end. After messing a bit more with the art style, I decided to do some animations for it as well. It is simple to do; all you need is the same picture in a few different ways in different positions, which resulted in this animation (effect).

Ghost Character Movement in Unity game development engine

Think back to the book animations. We get the animation below from these four main character styles: 

Ghost Character Movement GIF

The Features of the Game: Ghostly Come Alive

What are the main features of Ghostly, you wonder? What's the main gameplay loop? The following sections answer these and many more Unity game-related questions!

Main Character and Gameplay Mechanics

In Ghostly, players can move the cute ghost character in two positions, up and down. They have three lanes to choose in which the ghost can stand to avoid getting hit by obstacles. The controls are simple; the player just needs to press the ‘Up’ or the ‘Down’ buttons to move the character. 

The game is an endless runner that brings in different obstacles in the form of enemies. If you hit them, you lose health. And if your character gets hit three times, the game will be over. When you are defeated, you have a restart screen that shows up; all you have to do to restart the run is press the ‘R’ button. This makes the gameplay more intuitive and easier to keep playing Ghostly.

There’s also a point system that keeps a score of how you’re doing; more on this later. As I said, this was my first project, so I didn’t include many complicated features; I tried to do the basics and ensure the game had a game loop and was bug-free. I suggest you do the same because it's always a good practice to do little but refine and optimize it.

Graphics of the Obstacles in the Unity Game Development Engine

I decided to do some black-goo-type enemies/obstacles with spikes on the outside to hint the player to the possibility of getting hurt. I could have done the animation for them like I did with the Ghost character, but I decided to do it differently. So, I added some vibrations to make it appear like the obstacles were pulsating.

Enemy or Obstacle Character

The Scoring System in Ghostly: My First Unity Development Engine Game

Ghostly features a scoring system that rewards players for their performance based on how long they last (oops). I had several ideas in mind when it came to doing this system, such as a time-based approach, the number of enemies escaped, or a mix of both.

Ultimately, I decided with the scoring system of the number of enemies you pass. This game mechanic encourages players to strive for higher scores, increasing competitiveness. This, in turn, also makes the player more to beat the highest score of their friends. Here's what the score source code (try saying it ten times quickly) looks like:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Score : MonoBehaviour {

    public int score;
    public Text scoreDisplay;

    private void Update()
    {
        scoreDisplay.text = score.ToString();
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        score++;
        Destroy(other.gameObject);
    }
}

Here's the analysis of the code above:

  • score: This is the variable that I use to keep the score.
  • scoreDisplay: This references the UI Text element that displays the player's score.
  • OnTriggerEnter2D(): This is a Unity method that is automatically called when 2D collider attached to the game object collides with another. collider.

The Process of Creating the Game on Unity Game Development Engine: Ghostly Come to Life

Creating this game was a challenging task for me since I was a newbie. I only had the knowledge gained from researching and trying to test out what I had learned.

There were a lot of struggles, moments I thought I couldn’t do it, bugs, oh lots of bugs, but in the end, I managed to make a functional prototype. I was so relieved when I finally got it working as intended.

The Development Process and The Tools Used: Unity Game Development Engine and Adobe Photoshop

The development of Ghostly involved a combination of two tools, the Unity Game Development engine and Adobe Photoshop. Adobe Photoshop helped me in making the graphics while the Unity Game Development engine obviously managed the game mechanics and structure. Since I didn’t add any sound effects or background music to the game, I didn’t need to use any other sound compiling tools.

The first step was to set up the scene of the game with the main camera and the sprites for the various parts of the game. After that, I added the sprites, background environment, Ghost character, obstacle/enemy (duplicating for multiplicity), and a simple particle that was used in animating the main character's movement. 

Later, some of these sprites became prefabs, pre-configured game objects that you can re-instate by your game logic. NOTE: Not all sprites need to be turned into prefabs.

The first thing that I started working on was the script for the player movement. Luckily for me, I already knew C# programming from school. So, I was fairly confident with my code, and I was able to write it in a short amount of time. If you're new to C# as well, then you will need some time to get familiar with its syntax. This game has, in total, eight scripts that help it run smoothly. These scripts are: Background, Destroyer, Obstacle, Obstacle Spawn, Player, Restart, Score, and Spawner, as shown below.

Asset Scripts Unity development structure

Challenges Faced During Unity Game Development

Developing Ghostly came with its fair share of challenges and bugs. Since I was new to using the Unity game development platform, I often had to go back and forth to follow the instructions I was learning. Also, my code obviously had some mistakes in it since no developer is able to write perfect code. I didn't worry too much about optimization initially. My main goal was to get the game working.

One of the funniest bugs I remember was when I had set up the movement of the player wrong. On pressing up and down too quickly, Ghostly movements did not align with the line. This meant that if I could do it a couple of times quickly, the character would go out of screen. The game would continue running as normal and even count the score; safe to say no one could have ever beaten the high score with that strategy, haha. Imagine being basically invincible; the game could run forever.

Timeframe for Completion

Creating Ghostly took approximately six months, from the initial concept to the final release. However, you have to keep in mind that I worked on this game just on the weekends, and it was a passion project more than something I wanted to do full-time or dedicate a lot of my time to. It might take you longer or shorter, depending on your prior experience with Unity game development engine and C#.

Ghostly Gameplay: My First Unity Development Engine Game

Here's the gameplay of the game I created. I have uploaded it on YouTube, so you can see the final output of how it looks here:

https://youtu.be/egwtI7bzl_4

Potential Future Plans: Beyond My First Unity Development Engine Game

If I were to continue working on this project, there are a couple of things I would add and do differently. The number one thing I would do is to add a main menu screen where the player decides when to start the game, rather than it immediately starting when you open the application. 

Next, I would revamp the scoring system as I think it’s a bit boring, and it doesn’t work properly. Thinking of it, I would do a mix of time passed + enemies passed and calculated a score based on that. (Also, there’s a bug that, when you die, the score counts the enemies that are on screen, but shh, don’t tell anyone.)

Moreover, I would completely change the way the enemies spawn, there are a few patterns as of right now, but there needs to be more than just constant enemies spawning. Maybe some sort of like a timer with waves that works in the background and makes the difficulty a bit easier as you go on. The concept of speeding the enemies when coming to the player is not the best, as it can be frustrating in the later stages of the game.

I would also consider adding a few power-ups, such as 2X points for a limited time. This could add more strategic elements to the game and make it more interesting.

Finally, I would consider adding some sound effects and music to the game so that it gives a full experience. As of right now, the gaming experience is not the best, and it doesn't feel complete. If you have any suggestions or improvements to make to the game, I'm happy to read them in the comment section below.

Closing Thoughts

The journey of creating Ghostly with the Unity Game Development platform for me has been amazing! I’ve learned so much, and I’m proud of what I was able to achieve all on my own. Even though it was a simple game I’ve enjoyed playing it a few times. I have a lot of ideas to improve the game, but that's for the future.

Let me know what you think of the game and if you found this article helpful. If you liked this article, please like the post. It would be great if you could also share your thoughts or experiences using Unity game development engine. If there are any questions, please ask in the comments.

More articles: Mojo Language 101 and Colossal AI: A Deep Dive.

Edited by: Syed Umar Bukhari.