Search Unity

Coroutine trouble (stop coroutine with a condition)

Discussion in 'Scripting' started by opeca, Nov 29, 2013.

  1. opeca

    opeca

    Joined:
    Sep 17, 2013
    Posts:
    19
    Hello All,

    My problem is, that I have a simple coroutine eg. like this one:

    Code (csharp):
    1.     public IEnumerator Test()
    2.     {
    3.         while (???)
    4.         {
    5.             Debug.Log("coroutine");
    6.             yield return null;
    7.         }
    8.     }
    I have an update cycle as well:

    Code (csharp):
    1.     private void Update()
    2.     {
    3.         if (Input.GetMouseButtonDown(0))
    4.         {
    5.             StartCoroutine(Test());
    6.         }
    7.     }
    So currently as you see it's working, when I push the mousebutton down, the above coroutine will be started. But I'm in trouble because I would like to solve, that if I push the button down, the actually running coroutine should be stopped before running the coroutine again.

    I know, that there is a stopcoroutine method in Unity, but I think, the concept of the coroutines is the conditions, and not the forced stop.

    Thank you
     
  2. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,706
    Here are two ways:

    1. If this is the only coroutine for this MonoBehaviour, use StopAllCoroutines(). Example:
    Code (csharp):
    1. private void Update()
    2. {
    3.     if (Input.GetMouseButtonDown(0))
    4.     {
    5.         StopAllCoroutines();
    6.         StartCoroutine(Test());
    7.     }
    8. }
    The downside is that this stops the coroutine immediately. If the coroutine needs to run some cleanup before exiting, you shouldn't use this.


    2. Or use a flag. Here's one suggestion:
    Code (csharp):
    1. private enum CoroutineState = { Inactive, Active, Reset };
    2. private CoroutineState coroutineState = CoroutineState.Inactive;
    3.  
    4. private void Update()
    5. {
    6.     if (Input.GetMouseButtonDown(0))
    7.     {
    8.         switch (coroutineState) {
    9.         case CoroutineState.Inactive: StartCoroutine(Test());
    10.         case CoroutineState.Active: coroutineState = CoroutineState.Reset; break;
    11.         default: break;
    12.         }
    13.     }
    14. }
    15.  
    16. public IEnumerator Test()
    17. {
    18.     coroutineState = CoroutineState.Active;
    19.     while (???)
    20.     {
    21.         Debug.Log("coroutine");
    22.         if (coroutineState == CoroutineState.Reset)
    23.         {
    24.             StartCoroutine(Test());
    25.             yield break;
    26.         }
    27.         yield return null;
    28.     }
    29.     coroutineState = CoroutineState.Inactive;
    30. }
    Don't use StopCoroutine(). It only accepts a string, which means you have to invoke StartCoroutine with a string name (e.g., StartCoroutine("Test")), which is prone to typo bugs.
     
  3. opeca

    opeca

    Joined:
    Sep 17, 2013
    Posts:
    19
    Thank you!

    It's working!
     
  4. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,706
    Happy to help!