‘Dodge The Spike’-Endless Runner Tech Blog

This blog contains the steps required to make an Endless runner game similar to the famous Dinosaur Game. I have used Unity as my game engine and the scripts are written in C#.

Note: I will be updating this blog as I am still working on the game.

Creating the character

Create an empty game object and add the Sprite Renderer component to it

Sprite Renderer Component
  • Set the layer of the game object to ‘Player’ and rename the object to ‘Player’
Player tag

Add the RigidBody2D component to the Player

RigidBody2D Component
  • Change the body type to Dynamic. Under constraints, freeze the Z axis rotation. This is done so that the player does not rotate about its Z axis when any collision occurs.

Add the BoxCollider2D component to the Player

Box Collider 2D
  • Click on ‘Edit Collider’ and adjust the box collider appropriately.
Box Collider

Creating the background

Create a new rectangular tilemap

  • Create a duplicate of the child object(tilemap). Name the first one to ‘Background’ and the second one to ‘Collision’.
Grid
  • Add the desired assets in the tile palette to start designing the background.
Tile Palette
  • Draw on the Background tilemap and create the background as per your choice
  • Set the Layer to ‘Default’

Select the ‘Collision’ tilemap and add Tilemap Collider 2D, Rigidbody 2D and Composite Collider 2D components.

Under Tilemap Collider 2D, check ‘Used by Composite’.

Tilemap Collider 2D
  • Under Rigidbody 2D, set the body type to static so that the object does not move once the game has started.
Rigidbody 2D
  • Draw the desired platform on the ‘Collision’ tilemap
Platform

Note: Ensure that you have selected the ‘Collision’ tilemap while drawing the platform.

  • Set the Layer to ‘Collision’

Player Movement

  • Create a new C# script and add it to the player.
  • Name it ‘PlayerMovement’
  • This script will be responsible for the player’s movement. In this case, the player only has the abilty to jump.
using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerMovement : MonoBehaviour{public Vector3 jump;public float jumpForce = 2.0f;private Rigidbody2D rb;public bool isGrounded;private BoxCollider2D coll;float distToGround;void Start(){rb = GetComponent<Rigidbody2D>();jump = new Vector3(0.0f,2.0f,0.0f);coll = GetComponent<BoxCollider2D>();}void OnCollisionStay2D(){isGrounded = true;}// Update is called once per framevoid Update(){if(Input.GetButtonDown("Jump") && isGrounded){rb.velocity = new Vector2(rb.velocity.x,jumpForce);isGrounded = false;}}private void OnCollisionEnter2D(Collision2D other) {if(other.gameObject.CompareTag("Spike")){Destroy(rb.gameObject);}}}

Spike

  • The spike will act as the obstacle which the player has to jump over
  • The spike will be given a velocity in the negative direction so it would appear as if it is coming from the right side of the screen
  • Add a Polygon Collider 2D component to the spike
Polygon Collider 2D
  • Add Rigidbody 2D component and set the body type to Dynamic
  • Freeze the z-axis rotation
Rigidbody 2D
using System.Collections;using System.Collections.Generic;using UnityEngine;public class Spike : MonoBehaviour{public float speed = 10.0f;private Rigidbody2D rb;void Start(){rb = this.GetComponent<Rigidbody2D>();rb.velocity = new Vector2(-speed,0.0f); //to make the spike move in negative x direction}// Update is called once per framevoid Update(){if(transform.position.x < -11.5f){//this.gameObject.SetActive(false);}}}

This was just one instance of the spike

To spawn multiple spikes, we make a prefab of the spike and use the Instantiate method to spawn it

using System.Collections;using System.Collections.Generic;using UnityEngine;public class SpawnSpike : MonoBehaviour{public GameObject spike;public float respawnTime = 1.0f;void Start(){StartCoroutine(spikeWave());}private void spawnSpike(){GameObject a= Instantiate(spike) as GameObject;a.transform.position = new Vector2(Random.Range(11.0f,17.0f),-3.5f);}// Update is called once per frameIEnumerator spikeWave(){while(true){yield return new WaitForSeconds(respawnTime);spawnSpike();}}}
  • Here we use the random function to randomly set the x position of the spike so that all the spikes are not equidistant from each other.
  • We also use IEnumerator to call the spawnSpike method after a few seconds (respawnTime=1.0f). This way, a new spike is spawned at a random position every second.

Score

  • Create an UI object for score and highscore.
  • Make appropriate changes
Score
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class Score : MonoBehaviour{public Text score;public float scoreAmount;public float pointIncreasedPerSecond;public AudioSource newHigh;public Text highScore;public bool soundPlayed;void Start(){scoreAmount=0f;pointIncreasedPerSecond = 1f;highScore.text ="HighScore: "+ PlayerPrefs.GetInt("HighScore",0).ToString(); //set default value to 0soundPlayed=false;}// Update is called once per framevoid Update(){score.text = "Score: "+ (int)scoreAmount;scoreAmount+= pointIncreasedPerSecond * Time.deltaTime;if ( scoreAmount > PlayerPrefs.GetInt("HighScore",0)){if (!soundPlayed) {newHigh.Play();soundPlayed = true;}PlayerPrefs.SetInt("HighScore", (int)scoreAmount);highScore.text = "HighScore: "+ (int)scoreAmount;}}public  void Reset() {PlayerPrefs.DeleteKey("HighScore");}}
  • The score is set to 0 and is incremented by 1 each second
  • If the score is greater than the highscore, then the highscore is updated

Buttons

  • Create 2 UI buttons, one for restart and one to reset the score
Buttons
  • Add onClick funtion in restart(play again) button and set the function to restart which is present in the RestartGame script
Restart
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.SceneManagement;public class RestartGame : MonoBehaviour{// Start is called before the first frame updatepublic void RGame(){SceneManager.LoadScene(SceneManager.GetActiveScene().name);Time.timeScale = 1;}}
  • Add onClick function in Reset button and add set the function to reset which is present in Score script

Attach Score script to Reset button object

Reset

--

--