Reset WaitForSeconds Coroutine

Hi everyone,

I am making a game where the player can pick up PowerUp’s. These PowerUP’s last for 30 seconds. I do do that by simply setting a bool to false in a coroutine. The problem is that if the player already picked the PowerUp up and picks it up agian within the 30 seconds the coroutine from the first PowerUP still runs. But I need to reset the coroutine to 30 seconds.

I tried to stop the coroutine with:

   if(collisiongameObject.CompareTag("Shield")
     {
         StopCoroutine("DeactivateShield");
         StartCoroutine(DeactivateShield(30));
     } 

and the coroutine:

IEnumerator DeactivateShield(float time)
    {
        yield return new WaitForSeconds(time);

        shieldActive = false;
       
    }

but this seems to just pause the Coroutine.

Is there a possibility to reset the coroutine or restart it?

1 Answer

1

From the docs: Note: Do not mix the three arguments. If a string is used as the argument in StartCoroutine, use the string in StopCoroutine. Similarly, use the IEnumerator in both StartCoroutine and StopCoroutine. Finally, use StopCoroutine with the Coroutine used for creation.

You can read more on StartCoroutine and StopCoroutine.

I tend to avoid WaitForSeconds, but it’s just a preference thing:

// Class-level reference to the shield routine if you have one
private Coroutine shieldRoutine;

if(collisiongameObject.CompareTag("Shield")
{
    if (this.shieldRoutine != null)
        StopCoroutine(this.shieldRoutine);
    
    this.shieldRoutine = StartCoroutine(DeactivateShield(30));
} 

IEnumerator DeactivateShield(float time)
{
    // GC purposes
    var instruction = new WaitForEndOfFrame();

    // Assume we're active by default
    this.shieldActive = true;

    // If you enter a non-positive time, this will be ignored
    while (time > 0) 
    {
        time -= Time.deltaTime;
        yield return instruction;
    }

    // Kill shield at the end
    this.shieldActive = false;
}

Works perfect. Thank you for your awnser!

Is there any specific reason that you are not choosing WaitForSeconds? I am new to Unity and do not really understand these routine things so I am just curious. Also, I have the same problem and thanks for your solution.