Daily Unity Notes

Andrei Marks · February 14, 2012

Coroutines! Yield!

The behavior of Coroutines is more like time slicing than threading as all coroutines are executed from the main thread.

http://unity3d.com/support/documentation/Manual/Execution%20Order.html

  • yield; The coroutine will continue after all Update functions have been called on the next frame.
  • yield WaitForSeconds(2); Continue after a specified time delay, after all Update functions have been called for the frame
  • yield WaitForFixedUpdate(); Continue after all FixedUpdate has been called on all scripts
  • yield WWW Continue after a WWW download has completed.
  • yield StartCoroutine(MyFunc); Chains the coroutine, and will wait for the MyFunc coroutine to complete first.

Coroutines are reentered at the point where they returned.

I think that is all the public information about Coroutines. It’s always safest to avoid making assumptions based on the underlying implementation since it is not public and could therefore change at any time.

More info:

http://unity3d.com/support/documentation/ScriptReference/index.Coroutines_26_Yield.html

http://unity3d.com/support/documentation/ScriptReference/Coroutine.html

You can’t use coroutines like that from Update. You can start coroutines in Update, but you can’t yield on them (since using yield can only be done in a coroutine). Update happens once every frame regardless, and will never pause for anything. When scheduling a sequence of events with coroutines, it’s much simpler just to avoid using Update entirely, since it’s not appropriate for that kind of code.

http://answers.unity3d.com/questions/119076/coroutines-vs-updatefixedupdatelateupdate.html

http://unity3d.com/support/documentation/ScriptReference/index.Coroutines_26_Yield.html

http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.StartCoroutine.html

IEnumerator DoSomething(float TimeToDie) { float elapsedTime = 0; while(elapsedTime < TimeToDie) { // Perform logic here elapsedTime += Time.deltaTime; yield return new WaitForEndOfFrame(); } }

Just start that coroutine like you normally would, and don’t put any logic in there that “blocks” the statement, i.e. something that is processor-intensive, or takes a long time to complete.

You can only yield from within a coroutine. Don’t do it anywhere else. Coroutines have to be started with StartCoroutine(), must have the return type IEnumerator, and must contain one yield return ___;.

http://answers.unity3d.com/questions/19978/a-while-type-statement-in-the-update-function-yiel.html

http://www.bydesigngames.com/2011/06/14/tutorial-coroutines-pt-1-%E2%80%93-waiting-for-input-infiniteunity3d/

C# Generic Lists use .Count NOT .Length.

IEnumerator

A little knowledge here for people who are saying “wtf is an IEnumerator?” If you check this msdn docs on this interface you will see in this case it is used to read through enumeration data. This line is in the ref docs: “Enumerators can be used to read the data in the collection, but they cannot be used to modify the underlying collection.” So basically every frame we’re stepping through another index of an enumeration. We don’t really need to know more, how or why in this case because Unity is going to handle all of this for us. All we need to know is how to set it up…

Else

So what I do is for anything that needs initiating values, I do that in Awake, and then my Level Manager begins the level in its Start method.

Twitter, Facebook