Add a delay to death to show animation

I want to add a delay from death to restarting the level. I’m assuming I’ll need a Coroutine, but I haven’t wrapped my head around how those work yet. I think it needs to be in PlayerMovement on the Die() function, but I’m not sure.

Here is the code I currently have

    void Die() {
        {
            if (myBodyCollider.IsTouchingLayers(LayerMask.GetMask("Enemies", "Hazards")))
            {
                isAlive = false;
                AudioSource.PlayClipAtPoint(deathSFX, Camera.main.transform.position);
                myAnimator.SetTrigger("Dying");
                myRigidbody.velocity = deathKick;
                myBodyCollider.enabled = false;
                myFeetCollider.enabled = false;
                FindObjectOfType<GameSession>().ProcessPlayerDeath();
            }
        }
    }

First, you have to be aware that processing in frames will continue to run during this delay. So things like player movement will continue to be processed unless you deal with that situation, like checking isAlive whenever you do stuff that shouldn’t happen when the player is dead.

That being said, coroutines are not that complicated. It’s just a mechanism that allows us to ‘spread’ a method’s code over multiple frames. Other than that, it’s still just a method that runs from top to bottom - or other, earlier exit points.

You could define the code inside the ‘if’ in a coroutine. Let’s also pass the number of seconds we want to delay to it

private IEnumerator DoDeathRoutineDelayed(float delaySeconds)
{
    // Do all the deathy stuff. It runs immediately
    isAlive = false;
    AudioSource.PlayClipAtPoint(deathSFX, Camera.main.transform.position);
    myAnimator.SetTrigger("Dying");
    myRigidbody.velocity = deathKick;
    myBodyCollider.enabled = false;
    myFeetCollider.enabled = false;

    // now we delay the reset
    yield return new WaitForSeconds(delaySeconds);

    // I am assuming this resets the level. Call it after the delay
    FindObjectOfType<GameSession>().ProcessPlayerDeath();
}

All the original code will run immediately up to the yield return. Here, we return, telling Unity that we only want to be called again after delaySeconds seconds. When those seconds have passed, Unity will call the method again, and it will continue from this line, moving on to call ProcessPlayerDeath() on the GameSession.

Now you can start the coroutine - if it has not already been started

Coroutine _deathRoutine; // Put this global to the class

private void Die()
{
    if (_deathRoutine != null)
    {
        // We are already doing the routine. Do nothing
        return;
    }

    if (myBodyCollider.IsTouchingLayers(LayerMask.GetMask("Enemies", "Hazards")))
    {
        // We are dead and have not started the routine yet. Delay reset for 2 seconds
        _deathRoutine = StartCoroutine(DoDeathRoutineDelayed(2f));
    }
}

The global _deathRoutine variable allows us to check if we’ve already started the routine. We only want to start it once. Alternatively, you could just check the isAlive variable and if it’s false it also means we’ve started the routine because we set it to false in the routine. If we have, just exit the method 'cos nothing else is needed here. Otherwise, if we are ‘touching the layers’ we’ve died, and we can start the routine

thanks you so much! I think in my mind I had Coroutines being a lot harder than they are.

When I first saw coroutines, I avoided them for a while until I discovered what they really are. I use them a lot now. Probably too much

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms