Home > front end >  I cant stop this coroutine in c#/Unity
I cant stop this coroutine in c#/Unity

Time:11-18

SOLVED I was looking in the wrong place. I could see gameOver turn to true but other code made it turn back to false before Coroutine could get stopped...

I have a coroutine I just can't get to stop. This obviously sounds like a duplicate and is probably an easy fix but I've read so many examples, documentation, and other people's problems around this now I'm going crazy. Can someone tell me what I'm doing wrong? I've tried a bunch of different options in the code like: Not caching the CR when starting/stopping it. Starting/Stopping CR with a name string. I've tried using "true" in the while loop and then breaking out other ways (if conditions, other bools).

Everything is in the same MonoBehaviour in the same file. I see gameOver gets set to true in logs. (Code that changes gameOver to true is not in snippets below though)

The Move() should stop executing both from gameOver going true and from stopping the CR right?

private float moveDelay = 0.4f;
private bool gameOver = false;
 
void Start() {
     StartCoroutine(Mover());
}
 
void Update()
{
    if (gameOver)
    {
        StopCoroutine(Mover());
        StopAllCoroutines;
    }
}

private IEnumerator Mover()
 {
     while (!gameOver)
     {
         Move();
         yield return new WaitForSeconds(moveDelay);
     }
 }

CodePudding user response:

Put it inside an variable to stop the one single coroutine. If you are using the StopAllCoroutines, call it with the (), like this: StopAllCoroutines();

private float moveDelay = 0.4f;
private bool gameOver = false;
private IEnumerator myCoroutine;
 
void Start() {
     myCoroutine = Mover();
     StartCoroutine(myCoroutine);
}
 
void Update()
{
    if (gameOver)
    {
        StopCoroutine(myCoroutine);
        //StopAllCoroutines();
    }
}

private IEnumerator Mover()
 {
     while (!gameOver)
     {
         Move();
         yield return new WaitForSeconds(moveDelay);
     }
 }

CodePudding user response:

Fix it like this:

    private float moveDelay = 0.4f;
    private bool gameOver = false;
    private Coroutine _coroutine;

    void Start() {
        _coroutine = StartCoroutine(Mover());
    }

    void Update()
    {
        if (gameOver)
        {
            StopCoroutine(_coroutine);
        }
    }

    private IEnumerator Mover()
    {
        while (!gameOver)
        {
            Move();
            yield return new WaitForSeconds(moveDelay);
        }
    }

CodePudding user response:

A simpler way of getting the same effect would be to use InvokeRepeating in your start method and then stop it once your gameOver condition is met, like so:

private float moveDelay = 0.4f;
private bool gameOver = false;
 
void Start() 
{
     InvokeRepeating("Move",0,moveDelay); //Function to run, Start Delay, Repeat delay
}
 
void Update()
{
    if (gameOver)
    {
        CancelInvoke(); //Note: you can specify a single invoke to cancel or leave it blank to cancel all invokes
    }
}
  • Related