Player death and delay before scene change

I’m looking to add a delay between the player death and the scene change.
At the moment my player dies, disappears, has an explosion effect, and then the level wont change.
Or I can have the player die, not disappear, explosion effect, and then the level will change.

It seems like something very simple and silly. Any advice?


// Player Controller Script

<...>
    //Collision&Score
    void OnTriggerEnter2D(Collider2D collider) {
        Projectile missile = collider.gameObject.GetComponent<Projectile>();
        if (missile) {
            Debug.Log("Enemy hit by laser");
            health -= missile.getDamage();
            missile.Hit();
            //When the player dies
                if (health <= 0) {
                // Explosion animation/effect on player location
                GameObject explode = Instantiate(explosion, transform.position, gameObject.transform.rotation);
                //Call Die(); and delay for 2 seconds
                Invoke("Die",2f);
                GameObject.Destroy(gameObject);
            }
        }
    }
    //Die
    void Die() {
        LevelManager lose = GameObject.Find("LevelManager").GetComponent<LevelManager>();
        lose.LoadScene("Win Screen");
    }

I have a possible suggestion: instead of destroying the player (which makes the Invoke call stop working), why not just disable its sprite renderer component so it becomes invisible?

Just replace

GameObject.Destroy(gameObject);

with

gameObject.GetComponent<SpriteRenderer>().enabled = false;

EDIT: Just realized a problem with that solution: you can keep shooting after “dying” (i.e. becoming invisible). So you could implement an isDead boolean flag and only allow shooting while isDead is false… but it’s becoming a bit messy.
Hopefully someone else comes up with a neater solution ^^’

Why not use a Coroutine?

Just make sure to make an int variable called dieTime and give a value of 2f.

I have not tested the below, so I cannot advise if this will work, but I don’t see why it wouldn’t.

//Collision&Score
void OnTriggerEnter2D(Collider2D collider)
{
    Projectile missile = collider.gameObject.GetComponent<Projectile>();
    if (missile)
    {
        Debug.Log("Enemy hit by laser");
        health -= missile.getDamage();
        missile.Hit();
        //When the player dies
        if (health <= 0)
        {
            // Explosion animation/effect on player location
            GameObject explode = Instantiate(explosion, transform.position, gameObject.transform.rotation);
            //Call Die(); and delay for 2 seconds
            GameObject.Destroy(gameObject);
            StartCoroutine("Die");
            
        }
    }

    IEnumerator Die()
    {
        yield return new WaitForSeconds(dieTime);
        LevelManager lose = GameObject.Find("LevelManager").GetComponent<LevelManager>();
        lose.LoadScene("Win Screen");

    }
}

@Sebastian_Martens messy or not it’ll get the job done. Thanks Deb. You’re helping me think outside the box.

edit: That worked beautifully well. Such an easy solution with the exact intended result. Thank you again @Sebastian_Martens


@Wadricks I see this a lot online. I’m simple not familiar with this method so I kept avoiding it until I studied it, but I suppose I should start that now and implement this all as an option to fix my code. Thank you Wadricks.

@Wadricks I wasn’t able to actually get this working with this method. After seeing it everywhere online when researching a solution I’ll definetly give it a better read to understand what this does and when to use it. Thank you for bringing this up Wadrick!

No problem, what kind of error did you get when you tried it?

I think it’s the same problem as with the Invoke method: the coroutine will stop executing as soon as the gameObject is destroyed. After reflection I think another way of doing it would be to implement a coroutine as you suggested, but in a different script (LevelManager for instance) and send an OnPlayerDeath event to trigger it. But that’s slightly more involved.

Glad that worked out for you :slight_smile:

Ok, it sounds like the gameobject you are destroying has this script on it, that means when you destroy it you can no longer run it, as it has been removed.

So you could actually do this. and just remove the destroy function altogether.

I added the removal of the collider purely so nothing can hit it.

 IEnumerator Die()
{
   GetComponent<MeshRenderer>().enabled = false;
   GetComponent<Collider>().enabled = false;    

    yield return new WaitForSeconds(dieTime);
    LevelManager lose = GameObject.Find("LevelManager").GetComponent<LevelManager>();
    lose.LoadScene("Win Screen");

}

Yeah you both are correct with what was happening. It wasn’t so much as the coroutine @Wadricks suggested was giving an error as when I destroyed my gameObject it destroyed the rest of the script. I might aswell have been writing Destory(this) and I would have realized it sooner.

You guys are great, thank you!