Make a Player Invincible in Unity

Your player may pick up a power up so that they are temporarily invincible. Or you may want your player to have temporary invincibility right after they are hit by an enemy to balance gameplay. Here’s how to make a player invincible in Unity.

Make a player invincible: Player script: make a bool variable to show if invincibility is active, make a function to enable the variable and start a coroutine to set the variable to false after time. Power up script: start the function that enables the variable when the player hits the power up.

Set Up

This example will use four gameobjects: a cube for the floor, a capsule for the enemy, and a cube for the player and invincibility power up. IMAGE 1 BELOW.

You will also need a script attached to the player and power up gameobjects. In this example the player script is called ‘PlayerInvinc’ and the power up’s is called ‘InvincTempPower.’ Remember to attach each script to its gameobject.

Next, select the Player in the Hierarchy window and in the Inspector window near the top, change the tag to ‘Player.’ Also, select the Enemy in the Hierarchy window and select the Tag dropdown box in the Inspector window. Then Click ‘Add tag….’ Click on the ‘+’ button to add a new tag. In the box that has the ‘New Tag Name’ label by it, type in ‘Enemy’ for the name and click ‘Save.’

Finally, select your power up gameobject in the Hierarchy and go to the Inspector. In the Box Collider component, select the ‘Is Trigger’ checkbox. A trigger is used for starting events and is ignored by the physics engine. This is perfect for a power up.

PlayerInvinc Script

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

public class PlayerInvinc : MonoBehaviour
{
    private bool invincibleEnabled = false;
    [SerializeField]
    private float invincCooldown = 3.0f;
    private int speed = 5;

private bool invincibleEnabled = false; – This line declares a boolean variable named invincibleEnabled. It then initializes the value of the variable to false as a default. This variable will be used in the function that enables the invincibility and the function that disables it. It is then used to see if the player should be destroyed or not when they are hit by an enemy. You’ll see below.

[SerializeField] – This allows the variable below it to be seen in the Inspector window even though the variable is private.

private float invincCooldown = 3.0f; – This line declares a float variable named invincCooldown and initializes its value to 3. This will be used to set how long they player will stay invincible after they collect the power up.

private int speed = 5; – This variable isn’t important for this example. It will be used for how fast the player can be moved.

 void Update()
    {

            float horizontalInput = Input.GetAxis("Horizontal");
            float verticalInput = Input.GetAxis("Vertical");

            Vector3 direction = new Vector3(horizontalInput, 0, verticalInput);

            transform.Translate(direction * speed * Time.deltaTime);
       
    }

In this case, Unity’s Update() function contains only the player’s movement code.

float horizontalInput = Input.GetAxis(“Horizontal”); – This isn’t important for this example either, but it declares a variable named horizontalInput, and then initializes it to control the horizontal axis in Unity’s Input Manager. This will be used to move the player along the Z axis.

float verticalInput = Input.GetAxis(“Vertical”); – This declares a variable named verticalInput, and then initializes it to control the Z axis in Unity’s Input Manager. This will be used to move the player along the Z axis. Z axis isn’t the vertical axis, but the variable was named verticalInput to better describe the axis it retrieved from the Input Manager.

Vector3 direction = new Vector3(horizontalInput, 0, verticalInput); – This line declares a Vector3 variable named direction and for the x value uses horizontalInput and for the z value uses verticalInput to move the player left, right, forward, and backward.

transform.Translate(direction * speed * Time.deltaTime); – This line uses the transform.Translate function to move the character in the direction the player chooses. direction is the Vector3 which is multiplied by the speed variable to move the player. It is then multiplied by Time.deltaTime, because if it wasn’t movement would be ridiculously fast.

    private void OnCollisionEnter(Collision collision)
    {
        
        if (collision.gameObject.CompareTag("Enemy"))
        {
            if (invincibleEnabled == false)
            {
                Destroy(gameObject);
            }
            
        }
    }

private void OnCollisionEnter(Collision collision) This function detects if one collider enters another colliders boundaries. Since this script is attached to the player gameobject, we will be checking if another gameobject’s collider has entered our player gameobject’s collider.

This function is passed the Collision class which contains information about the collision itself. So we will be able to detect which collider touched our player’s collider and then execute specified code.

if(collision.gameObject.CompareTag(“Enemy”)) – Remember when we gave the Player and the Enemy gameobjects tags? This is what it is for. Using the CompareTag() function, we are checking if the gameobject that the player collided has the Enemy tag. If it does have the Enemy tag, then it will execute the code within the if statement.

If we didn’t have this check, then the player could be destroyed just by touching the ground or a wall. We only want the player to be destroyed by touching an enemy in this example.

if (invincibleEnabled == false) – This is an if statement to check if a condition in the code is true. Here we check if the boolean variable invincibleEnabled is false. If it is false, then we will execute the code that is contained in the if statement.

This next function is needed because if a player is invincible and continues to touch an enemy even after invincibility is disabled, the player gameobject will not be destroyed until after the player moves away from the enemy and then touches it again. This is not what we want, so check out the code below.

private void OnCollisionStay(Collision collision)
    {
        if (collision.gameObject.CompareTag("Enemy"))
        {
            if (invincibleEnabled == false)
            {
                Destroy(gameObject);
            }
        }
    }

private void OnCollisionStay(Collision collision)This function detects if a collider is staying inside the boundaries of another collider, or touching the other colliders boundaries. You can see that, again, it takes the collision class as it’s parameter to get access to information about the collision that has occurred.

if(collision.gameObject.CompareTag(“Enemy”)) – Again, using the CompareTag() function, we are checking if the gameobject that the player collided has the Enemy tag. If it does have the Enemy tag, then it will execute the code within the if statement.

if(invincibleEnabled == false) – This is an if statement to check if a condition in the code is true. Here we check if the boolean variable invincibleEnabled is false. If it is false, we know the player is not invincible. So we will execute the code that is contained in the if statement.

Destroy(gameobject); – This line removes from the scene, or destroys, the gameobject attached to this script. So it will destroy the player if it has collided with the enemy.

Let’s get into the functions that directly control the invincibility. We will code two functions in the Player script that do this.

public void InvincEnabled()
    {
        invincibleEnabled = true;
        StartCoroutine(InvincDisableRoutine());
    }

public void InvincEnabled() – This function will be used to turn on invincibility for the player.

invincibleEnabled = true; – Here is the boolean variable invincibleEnabled again. This line sets its value to true. When the value is true, the if statements in the OnCollisionEnter() and OnCollisionStay() functions that checks if it is false, will not run. Therefore, they will not destroy the player gameobject when it collides with an enemy.

So the invincibility part of the code is really just not allowing the Destroy(gameObject) line of code to execute where our script detects collisions. Pretty cool.

StartCoroutine(InvincDisableRoutine()); – We’re not done yet though. We can’t let our invincibility go on forever, so here is where the cooldown function is called. Note that we use a StartCoroutine() function. This starts the function to disable the invincibility. But what is a coroutine, and why do we need it?

A coroutine is a function that can have its execution stopped until a certain amount of time has passed.

We need this because we want our power up to be disabled after our invincCooldown variable has reached 0 seconds. After that time, our player will be vulnerable to collisions with the enemy. So see below for an explanation of our coroutine function.

IEnumerator InvincDisableRoutine()
    {
        yield return new WaitForSeconds(invincCooldown);
        invincibleEnabled = false;
    }

IEnumerator InvincDisableRoutine() – This is the coroutine that will end the player’s invincibility after enough time has passed. What’s that weird IEnumerator in the beginning?

IEnumerator is “the base interface for all non-generic enumerators.” It can be used to pause an iteration.

So IEnumerator pauses for a certain amount of time before something happens.

yield return new WaitForSeconds(invincCooldown); – In this line we use these yield instructions to stop the execution of InvincDisableRoutine()’ code for the amount of time specified in the WaitForSeconds() parameter, invincCooldown. So for this example, the suspension of the code execution would be for three seconds.

What this means is the invincibility will last for three seconds before the rest of the code in this function is executed.

WaitForSeconds halts the execution of a coroutine for the number of seconds specified in its parameter.

invincibleEnabled = false; – This line sets our invincibleEnabled variable to false. When this happens, the if statements in our collision functions that check if this variable is false will be able to execute their code, and thus destroy the player when it collides with an enemy. The power up’s lifecycle is now complete.

InvincTempPower Script

We’re almost done. The Player script is now complete. You’ll notice that function to start the invincibility is not called in that script. It will be called in the power up script after the user collides with the power up. Fortunately, this is a fairly simple script to read and understand.

private void OnTriggerEnter(Collider other)
    {
        PlayerInvinc player = other.transform.GetComponent<PlayerInvinc>();
        if (other.gameObject.CompareTag("Player"))
        {
            player.InvincEnabled();
            Destroy(this.gameObject);
        }

    }

private void OnTriggerEnter(Collider other) OnTriggerEnter() is a function that is similar to OnCollisionEnter(). It stores information from the Collider class about the collision that happened. You have to use OnTriggerEnter() instead of OnCollisionEnter() when the object it is for is a trigger collider, not just a normal collider. So when a collision occurs, code inside this function executes.

Note that when using OnTriggerEnter(), both gameobjects must have a Collider component, and at least one gameobject must have a Rigidbody component.

PlayerInvinc player = other.transform.GetComponent<PlayerInvinc>(); – This line creates a reference to the PlayerInvinc class attached to the player gameobject and names the reference player. ‘other’ is in reference to the parameter in the OnTriggerEnter() function. ‘other’ is the collision information for the gameobject that collided with the power up. In this instance, it will be the player gameobject.

So other.transform.GetComponent<PlayerInvinc>(); is the player gameobject’s class being accessed. This will allow the InvincTempPower class (or script) to access functions from the PlayerInvinc’s class. This will be used in the code below.

if (other.gameObject.CompareTag(“Player”)) – This if statement checks of the gameobject that collided with the power up has a tag called ‘Player.’ If it does, then it will execute the code within the if statement.

player.InvincEnabled(); – This line accesses the PlayerInvinc script attached to the player and calls the InvincEnabled() function. Thus, the invincibleEnabled variable is set to true. and the coroutine InvincDisableRoutine() is started. After 3 seconds, the invincibleEnabled variable will be set to false, allowing all the code in OnCollisionEnter() to be run.

Destroy(gameObject); – This line destroys, or removes, the power up from the scene.

Summing Everything Up

So that’s the end of the example. Remember that the invincibility executed in the script attached to the player. The power up script is there to turn the invincibility on, and that’s it. This method, or something similar can be used for other power ups that speed the player up, allow them to use a weapon, jump higher, and much more.

Similar Posts