Coroutines in Unity3d (C# version)

Coroutines in C# work the same way that they do in Javascript (UnityScript), the only difference is that they require more typing (they have a slightly more complicated syntax). You should see the blog post on Javascript coroutines first.

Here, I present the differences:

Coroutines must have the IEnumerator return type:

IEnumerator MyCoroutine()
{
	//This is a coroutine
}

To invoke a coroutine you must do it using the StartCoroutine method:

public class MyScript : MonoBehaviour 
{
    void Start()
    {
		StartCoroutine(MyCoroutine());
    }

    IEnumerator MyCoroutine()
    {
        //This is a coroutine
    }
}

The yield statement becomes yield return in C# :

IEnumerator MyCoroutine()
{
    DoSomething();
    yield return 0;	//Wait one frame, the 0 here is only because we need to return an IEnumerable
    DoSomethingElse();
}

Remember that we need to return an IEnumerable, so the Javascript yield; becomes yield return 0; in C#

Also, since C# requires you to use the new operator to create objects, if you want to use WaitForSeconds you have to use it like this:

IEnumerator MyCoroutine()
{
    DoSomething();
    yield return new WaitForSeconds(2.0f);	//Wait 2 seconds
    DoSomethingElse();
}

Happy coroutining :)

  • Pingback: Coroutines in Unity3d (Javascript version) - Silent Kraken

  • http://www.facebook.com/gtjuggler Alex Schwartz

    Thanks Seth for sharing these basics. Definitely useful to those looking to learn.

    One note: I had heard that returning null is ever so slightly faster than returning 0 when yielding in a coroutine due to the allocation for creating a new variable :)

  • http://cjcurrie.net/ cjcurrie

    So how do you create a coroutine that returns a value at the end?

  • http://rockingtech.blogspot.com Robert

    thanks for sharing the code for this. i really needed to know and i will use a slightly modified one in my application. What if i wanted to return more than one values. Is there any way i can do it.

  • Richard Hensman

    Hi,

    So according to Unity Docs, you can’t use yield in an Update statement, but you can start a CoRoutine that does.

    I am somewhat confused by this.  In my code I have two objects.  Object 1 needs to make two calls to Object 2.  Object 2, in each case, starts an animation, waits X seconds (local member of Object 2), then returns to Object 1.  So I think Object 2 code looks like:

    IEnumerator MethodTwo() {
    AnimationClip.play();
    yield return new WaitForSeconds(x);
    }

    But does Object 1 need to “yield” at all, or can it just call MethodTwo(); directly?

    Thanks,
    Rich

  • http://www.silentkraken.com/ Daniel Rodriguez

    If you want Object1 to wait for Object 2 it needs to yield StartCoroutine on Object2.

  • Chandan

    Thanks for the post

  • http://twitter.com/m_s_ramzy Mina Samy

    Hi, thanks for explaining
    I have a question: why use a coroutine instead of a regular method ?
    thanks

  • Dusan Petrovcic

     ok explain why this doesn’t work please

    [Code]
    using UnityEngine;
    using System.Collections;

    public class CraftPosition : MonoBehaviour {
        public bool Building = true ;
        public bool Builded = false ;
        public float smooth = 1 ;
        public float Distance = 3 ;
        GameObject Player ;
        public Create Script ;
       
        public float time ;
        public float time1 ;
        public Vector3 position ;
        void Start () {
            Player = GameObject.Find(“Camera”);
            Script = Player.GetComponent(“Create”) as Create;
        }

        IEnumerator Wait3Sec (){
            yield return new WaitForSeconds(3.0f);
        }

        void Update () {
           
            //snap in to player’s controll
            if (Building){
                Player = GameObject.Find(“Camera”);
                transform.position = Vector3.Lerp (transform.position , Player.transform.position + Player.transform.forward * Distance , Time.deltaTime * smooth);
            }
           
            // change craft object to gravity and snap out of player’s controll
            if (Building){
                if (Input.GetKeyDown(KeyCode.Mouse0)){
                    transform.rigidbody.useGravity = true ;
                    Building = false ;
                    Builded = true ;
                   
                }
            }
            // after 3 sec make object to kinematic so it’s builded object
            if (Builded == true){
                position = transform.position;
                time = Time.time;
                //while (position == transform.position || time1 – time < 3) {
                StartCoroutine(Wait3Sec());
                //time1 = Time.time;
                transform.rigidbody.isKinematic = true;
                //}
                Script.NotBuilding = true;
                Builded = false ;
            }
        }
    }

    [/Code]

  • adios

    now thats an explanation..

  • Juh Hi

    Good! Thanks for your explaining.

  • kent

    Thanks for posting!