How to Create Game Over State in Unity in 10 Minutes

You can access the full course here: CREATE YOUR FIRST 2D GAME IN UNITY

Game Over – Part 1

In this lesson, we’ll set up the Game Over state for our game. In our game, the Game Over state will happen either when the Player hits an Enemy, or when the Player falls from the level.

The Game Over Function

To implement the Game Over state, we’ll go to the PlayerController script and do the following changes:

  • Add the SceneManagement library at the top of the script
  • Add the GameOver function to the PlayerController script
  • In the GameOver function, use the LoadScene function to reload the current scene
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; // Add me!!

public class PlayerController : MonoBehaviour
{
    // Older code omitted for brevity
    // Called when we get hit by an enemy or if we fall below the level.
    public void GameOver ()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

And here’s what the PlayerController script looks like at the moment:

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

public class PlayerController : MonoBehaviour
{
    public float moveSpeed;
    public Rigidbody2D rig;
    public float jumpForce;
    public SpriteRenderer sr;

    private bool isGrounded;

    void FixedUpdate ()
    {
        float moveInput = Input.GetAxisRaw("Horizontal");
        rig.velocity = new Vector2(moveInput * moveSpeed, rig.velocity.y);

        if(rig.velocity.x > 0)
        {
            sr.flipX = true;
        }
        else if(rig.velocity.x < 0)
        {
            sr.flipX = false;
        }
    }

    void Update ()
    {
    // If we press the jump button and we are grounded, then jump.
        if(Input.GetKeyDown(KeyCode.UpArrow) && isGrounded)
        {
            isGrounded = false;
            rig.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
        }
    }

    private void OnCollisionEnter2D (Collision2D collision)
    {
        if(collision.GetContact(0).normal == Vector2.up)
        {
            isGrounded = true;
        }
    }

    // Called when we get hit by an enemy or if we fall below the level.
    public void GameOver ()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

The Fall Game Over Challenge

As a bit of a challenge, we want you to implement one of the game-over cases yourself. In this challenge, you should make the fall-from-the-level scenario work as a game-over.

One of the ways to do so is to check whether the Player’s vertical position is below some level. Checking could be done in the Update function.

In this lesson, we implemented the Game Over function. In the next lesson, we’ll implement the game-over scenarios.

Game Over – Part 2

In this lesson, we’ll implement the Game Over scenarios.

The Fall Game Over

To make the Game Over happen when the Player falls from the level, we should make the following changes to the Player Controller > Update function:

  • In the Update function, check whether the vertical position of the Player is less than -4
  • If so, call the GameOver function
// Using directives omitted for brevity

public class PlayerController : MonoBehaviour
{
    // Older code omitted for brevity


    void Update ()
    {
    // Older code omitted for brevity


    // If we fall below -4 on the Y, then game over.
    if(transform.position.y < -4)
    {
    GameOver();
    }
}

    // Older code omitted for brevity
}

If you start the game now and jump from the level, in a couple of seconds, the level will reload from the beginning.

game level

game level

Here’s what the PlayerController script looks like now:

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

public class PlayerController : MonoBehaviour
{
    public float moveSpeed;
    public Rigidbody2D rig;
    public float jumpForce;
    public SpriteRenderer sr;

    private bool isGrounded;

    void FixedUpdate ()
    {
        // Get the horizontal move input.
        float moveInput = Input.GetAxisRaw("Horizontal");

        // Set our velocity.
        rig.velocity = new Vector2(moveInput * moveSpeed, rig.velocity.y);

        // Flip the sprite to face our moving direction.
        if(rig.velocity.x > 0)
        {
            sr.flipX = true;
        }
        else if(rig.velocity.x < 0)
        {
            sr.flipX = false;
        }
    }

    void Update ()
    {
        // If we press the jump button and we are grounded, then jump.
        if(Input.GetKeyDown(KeyCode.UpArrow) && isGrounded)
        {
            isGrounded = false;
            rig.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
        }

        // If we fall below -4 on the Y, then game over.
        if(transform.position.y < -4)
        {
            GameOver();
        }
    }

    private void OnCollisionEnter2D (Collision2D collision)
    {
        if(collision.GetContact(0).normal == Vector2.up)
        {
            isGrounded = true;
        }
    }

    // Called when we get hit by an enemy or if we fall below the level.
    public void GameOver ()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

The Enemy Hit Game Over

We should also go to the Game Over state once the Player hits an Enemy. We’ll do this from the Enemy script.

But first, we need to add a way for an Enemy to know that it hits the Player, and not something else. Here’s what we’ll do:

  • Select the Player game object
  • Go to the Inspector window
  • Set the Tag property at the top of the Inspector window to the Player value

Now our Player is tagged as a Player. Well done!

Player game object

And here’s what we’ll do in the Enemy script:

  • Add the OnTriggerEnter2D function. This function is called when something enters the trigger collider
  • In this function, check whether we have a collision with an object tagged as a Player
  • If so, get the PlayerController component from that object and call the GameOver function on it
// Using directives omitted for brevity
public class Enemy : MonoBehaviour
{
    // Older code omitted for brevity
    private void OnTriggerEnter2D (Collider2D collision)
    {
        // Did the player hit us?
        if(collision.CompareTag("Player"))
        {
            // Trigger the game over state on the player.
            collision.GetComponent<PlayerController>().GameOver();
        }
    }
}

Now, if you jump into an Enemy, the game will reload as well. Here’s what the full Enemy script looks like:

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

public class Enemy : MonoBehaviour
{
    public float moveSpeed;
    public Vector3 moveOffset;
    private Vector3 startPos;
    private Vector3 targetPos;
    // Start is called before the first frame update
    void Start()
    {
        startPos = transform.position;
        targetPos = startPos;
    }
    // Update is called once per frame
    void Update()
    {
        // Move towards the target position.
        transform.position = Vector3.MoveTowards(transform.position, targetPos, moveSpeed * Time.deltaTime);
        // Are we at the target position?
        if(transform.position == targetPos)
        {
            // Is our target pos our start pos? If so, set it to be the other one.
            if(targetPos == startPos)
            {
                targetPos = startPos + moveOffset;
            }
            // Otherwise, do the opposite.
            else
            {
                targetPos = startPos;
            }
        }
    }
    private void OnDrawGizmos()
    {
        Vector3 from;
        Vector3 to;
        if (Application.isPlaying)
        {
            from = startPos;
        }
        else
        {
            from = transform.position;
        }
        
        to = from + moveOffset;
        
        Gizmos.color = Color.red;
        Gizmos.DrawLine(from, to);
        Gizmos.DrawWireSphere(to, 0.2f);
        Gizmos.DrawWireSphere(from, 0.2f);
    }
    private void OnTriggerEnter2D (Collider2D collision)
    {
        // Did the player hit us?
        if(collision.CompareTag("Player"))
        {
            // Trigger the game over state on the player.
            collision.GetComponent<PlayerController>().GameOver();
        }
    }
}

In this lesson, we implemented the Game Over scenarios. In the next lesson, we’ll work on the collectible Coins.

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.

Transcript – Game Over – Part 1

Welcome back everyone. In this lesson we are going to be working on setting up our game overstate for our 2D platform here.

So the way the game over state is gonna work is pretty much whenever our player gets hit by an enemy or if they fall off the edge and down below our level, they are going to basically reset, okay?

The level is gonna restart and the player will spawn back up here. Okay, so how do we do this? Well, let’s go over and open up our player controller script right here.

Now inside of the player controller script, we are gonna go down and create a brand new function. And this function is gonna be a public void called GameOver. Okay? Like so.

Now the reason we are making this function a public function is because we need to be able to call this from outside of the script. For example, our enemy script here is going to be able to call that function.

So in order to do that, we need to make it public. Now, inside of this function, what we are going to do is basically reload our current scene.

So in order to do that, we first of all need to tell the script that we want to be able to access Unity’s scene manager. And to do that we need to go to the top and you’ll see here we have these three lines of code, okay?

They’re basically using, and then we have a library here. Now, the way code and C Sharp especially works is that you don’t have everything at your disposal right at the start, okay?

So for certain things you may need to access a library. In our case, we are accessing the Unity engine library which allows us to access things such as mono behavior, rigid body, sprite renderer, the fixed update function, the update function, okay?

These are all things that are built into the Unity engine itself. Now, the Unity engine doesn’t always give us everything we need since there are a lot of different code libraries that we can access.

So if we wanna get specific, we do need to actually add them here. So for example, in order to access our scene manager, we need to be using the scene management library.

Now to do that, we can go to a new line here and just go using Unity engine dot scene management like so, and now we have access to our scene manager. So let’s go back down to our GameOver function.

And inside of here what we are going to do is go scene manager dot load scene, okay? And this function right here, basically we need to give it either a scene name, so we can just go level one like so, which is the name of our scene, or we can give it a build index.

And our build index for level one is zero. Basically, the levels go 0, 1, 2, 3, 4, 5, et cetera. But what if we’re on level five, for example? We don’t wanna have to hardcode every single level we have.

So, instead what we can do is we can just get whatever our current scene is and reload that. So to do this, I’m gonna go SceneManager dot GetActiveScene.

Now this is a function call, so make sure to add the two empty brackets like so, and then dot buildIndex. So this here is basically getting the index for the current scene and loading that.

So this line of code essentially reloads our current scene. So we have our game over function, but at the moment it’s not hooked up to anything just yet. So if we were to play our game, nothing would happen.

So in order to make something happen, we are first of all gonna make it so that if our player is jumping along the level here and they fall off the platform we don’t want them to keep on falling down forever.

Let’s say once they reach below, we’ll say below negative four, okay? Once they go below negative four on the Y axis that is when we will basically call the game over function.

So to do this, we are gonna go up to our update function right here. And as a bit of a challenge, I want you to have a go at implementing this.

Here’s a hint. Basically, we are gonna have an if statement that checks to see if our Y position is below negative three or negative four, I’m pretty sure we said, and if that’s the case call the game over function. So have a go at that and I’ll be right back to see how you’re done.

Transcript – Game Over – Part 2

Pretty much what we want to do is inside of our PlayerController’s update function we want to check every single frame if our player’s y position is below a certain number.

So what we’re gonna do is we’re gonna create an IF statement here. We’re gonna go, if transform.position.y is less than, let’s just say negative four then what we are going to do is we are going to call the GameOver function like so, okay?

So that is what we need to do here and make sure it is inside of the update function since we do want to check this every single frame. So we can save that, we can then go back inside of Unity now.

And if we press play, we should be able to test this out. So let us go over to the side right here and jump off the edge. And as you can see, once we go below negative four our scene basically gets to reset.

So we are back at the start and there we go. Now one more thing and that is our enemy. As you can see right now our enemy is just passing directly through us.

So we need a way of making it so that when the enemy hits us the GameOver function gets called. So how do we do that? Well, let us go over to our enemy script right here, and inside of the enemy script we need to create ourselves a brand new function.

Now this is going to be the OnTriggerEenter2D function. So we’re gonna go void OnTriggerEenter2D. Now OnTriggerEenter works very similar to OnCollisionEnter yet they both differ in a certain way.

Collision is basically a solid hit, so you can think of when our player lands on the ground their feet are being planted on the ground’s collider, whereas a trigger is passing through something, okay?

So maybe you might want to have some sort of trigger when a player walks through a door that would be a trigger, okay? The player isn’t blocked, they can pass through it, yet we can detect when that pass through happens.

And that is what a trigger is. So what we need to do is we basically need to make it so that when the player is hit by the enemy we call the GameOver function. But how do we do that?

Well, we’ve got the function here that detects when a trigger has happened, but how do we know if it was a player or not? How do we know that what the enemy hit is a player and not a wall, or a coin, or another enemy?

Well, the way we can do this is by checking to see what the player’s tag is. And before we continue writing code, let’s go back inside a Unity and we need to give our player a tag.

So I’m gonna select our player here and if we go over to the inspector, you’ll see underneath their name they have this little tag dropdown. Now tag is basically a label that we can attach to a game object.

So I’m gonna click on where it says untagged and you’ll see there are a few preset ones here. We can click add tag to add a new one. But we’ve got player, sorry, I’m just gonna select that.

And now our player game object is tagged as player. And you can of course, create tags for other things as well if that’s needed.

But we’re just gonna tag our player for now. So back inside of our script, what we’re gonna do is we are going to check to see if the collision.CompareTag is Player. So the parameter here is collision.

This is basically going to be our player’s collider when the enemy hits us and we are checking to see if that game object’s tag is player, and if so then the condition is true and we can call the GameOver function.

Now, in order to call the players GameOver function, we need to access their player controller component. So to access another game objects component or get any component in general, we need to do a certain function call.

So I’m gonna go collision.GetComponent, and then inside of these two angled brackets we need to define the type of component we are searching for which is gonna be PlayerController, and then two empty brackets like so.

And then we can go .GameOver. Whoops, not GameObject, GameOver, like so. So basically what we have done here is we have accessed the collision component that we have hit.

In this case it will be the player after we do this IF statement. Then we are getting another component on that GameObject we are searching for the PlayerController and then we are calling the GameOver function on the PlayerController.

So we can save that, go back inside of Unity and let’s test it out to see if it works. So I’m going to press play right here and if we jump up into our enemy, we should see that when it hits us the scene gets reset and we can even jump into the enemy here to make sure it works.

There we go. So we’re able to reset the scene by having our enemy run into us. So we need to avoid them on this jump here. And if we jump off our level and fall down below that will also reset the level as well.

So yeah, that is a look at our GameOver state inside of Unity. Now, in the next lesson, we are gonna be looking at setting up our coins, okay? These are basically going to be the collectibles that our player will collect and that will increase their score over time. So thanks for watching, and I’ll see you then in the next lesson.

Interested in continuing?  Check out our all-access plan which includes 250+ courses, guided curriculums, new courses monthly, access to expert course mentors, and more!