How to start a coroutine from Update.

Hi,

I check something in my Update function and depending on some parameters I start a coroutine that does something in 5 seconds.

Since Update is called constantly, it’s perfect to check for my condition but when it gets true, it will stay true and call the coroutine several times and I don’t think it’s good.

I can hackaway with a boolean but I was wondering if my approach is wrong since I’m new to Unity and coroutines. Here is my code:

	void Update ()
	{
		if (m_objectiveManager.IsObjectivesDone)
		{
			StartCoroutine("RestartGame");
		}
	}

	IEnumerator RestartGame()
	{
		Debug.Log ("We believe that game is over and will restart the game in 5 seconds.");
		yield return new WaitForSeconds(5.0f);
		Application.LoadLevel (Application.loadedLevel);
	}

There’s a way simpler solution: Don’t use Update at all :wink:

void Start()
{
    StartCoroutine(RestartGame());
}
 
IEnumerator RestartGame()
{
    while (!m_objectiveManager.IsObjectivesDone)
        yield return null;
    Debug.Log ("We believe that game is over and will restart the game in 5 seconds.");
    yield return new WaitForSeconds(5.0f);
    Application.LoadLevel (Application.loadedLevel);
}

you have two options

  1. This is your approach with some improvement:

    void Update ()
    {
    if (m_objectiveManager.IsObjectivesDone)
    {
    m_objectiveManager.IsObjectivesDone = false;
    StartCoroutine(“RestartGame”);
    }
    }

     IEnumerator RestartGame()
     {
        Debug.Log ("We believe that game is over and will restart the game in 5 seconds.");
        yield return new WaitForSeconds(5.0f);
        Application.LoadLevel (Application.loadedLevel);
     }
    
  2. I will suggest you to follow second one that is

    void Update(){

           if(Time.time - _lastTime > 5){
    
              _lastTime = Time.time;
               //  check your stament here and do the stuff
        }
    

    }

Setting a flag the first time the coroutine is called isn’t such a bad thing.

The alternative is having a state enum variable and switching it depending on the state of the game. So for instance it could be GameState.Playing normally, then set to GameState.Restarting when the coroutine gets run. State machines are common in games programming, just because games are very stateful systems usually.

If you’re not going to use states then a single flag set when the coroutine gets called and checked against the next time round isn’t a bad idea at all.

Hi, I think calling a Coroutine from Update is not the appropriate, but in case you want so:

void Update ()
     {
           if (m_objectiveManager.IsObjectivesDone)
           {
               //Just called once
               m_objectiveManager.IsObjectivesDone = false; //If the property/var can be set!
               StartCoroutine("RestartGame");
           }
    }
    
    //But if you're not using State Machines, you should call the Coroutine out of the Update
    //May be when you set the m_objectiveManager.IsObjectivesDone var like this
    
    //Not in the Update
    m_objectiveManager.IsObjectivesDone = true;
    //Something else
    //Then call the Coroutine
    StartCoroutine("RestartGame");

Hope it helps