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