エンジニア

Unityのコルーチンの使い方をまとめてみた

投稿日:2014年9月2日 更新日:

今回のエンジニアブログは大橋が担当します。
初登場です。よろしくお願いします。

さて、Unityにはコルーチンの仕組みが標準搭載されています。
コルーチンを使うと、
「処理1」→「一定時間待つ」→「処理2」→「一定時間待つ」→「処理3」
のような一連の処理を1つの関数で直感的に書けます。

ここでは、コルーチンがどういったものかという詳細は割愛させてもらって、
実際の使い方をまとめたいと思います。

動作確認環境

Unity 4.5
C#

 

コルーチンの書き方

コルーチンは、IEnumeratorを返す関数として実装します。
そして、StartCoroutineメソッドで実行します。
StartCoroutineの引数には、実行したいコルーチンの関数名を指定します。

public class Test : MonoBehaviour {
    void Start () {
        // コルーチンを実行  
        StartCoroutine ("Sample");
    }

    // コルーチン  
    private IEnumerator Sample() {
        // コルーチンの処理  
    }
}

ちなみに、上記のソースコードはコルーチン内の処理を書いてないので、「戻り値がない」というエラーになってしまうのでご注意!

 

コルーチンの途中で一定時間中断

コルーチンの真価は、その処理の途中で、一定時間中断することができるところです。
コルーチンの途中で次のように書くことで、処理が一時中断され、一定時間経過すると次の行から処理が再開します。
yield return new WaitForSeconds (秒数);

サンプル
private IEnumerator Sample() {
    // ログ出力  
    Debug.Log ("1");

    // 1秒待つ  
    yield return new WaitForSeconds (1.0f);

    // ログ出力  
    Debug.Log ("2");

    // 2秒待つ  
    yield return new WaitForSeconds (2.0f);

    // ログ出力  
    Debug.Log ("3");
}

 

コルーチンの途中で中断して次のフレームで再開

コルーチンの途中で次のように書くと、そこでいったん処理が中断され、次のフレームで処理が再開されます。
yield return null;

サンプル

1フレームごとにログを出力します。

private IEnumerator Sample() {
    for (int i = 0; i < 100; i++) {
        Debug.Log ("i:" + i);
        yield return null;
    }
}

 

コルーチンの途中で終了

コルーチンの途中で処理を終了するには、次のように書きます。
yield break;

サンプル

5回ループが回った時点でコルーチンを強制終了させています。

private IEnumerator Sample() {
    for (int i = 0; i < 10; i++) {
        Debug.Log ("i:" + i);
        yield return new WaitForSeconds (1f);

        // i==4になったらコルーチン終了  
        if (i == 4) {
            yield break;
        }
    }
}

 

引数があるコルーチンを実行

引数があるコルーチンに値を渡すには、StartCoroutineの第二引数に渡したい値を指定します。
ただし、この方法では2つ以上の引数に値を渡すことはできません。
StartCoroutine (コルーチン名, 引数に渡す値);

サンプル

StartCoroutineの第二引数で指定した回数だけループを回しています。

void Start () {
    // コルーチンに引数に5を渡して実行  
    StartCoroutine ("Sample", 5);
}

private IEnumerator Sample(int num) {
    for (int i = 0; i < num; i++) {
        Debug.Log ("i:" + i);
        yield return new WaitForSeconds (1f);
    }
}

 

2つ以上の引数があるコルーチンを実行

StartCoroutineでは、コルーチンの関数名を文字列で指定する以外に、StartCoroutineの引数内でコルーチン関数を呼び出すことでも、コルーチンを実行できます。
この方法でコルーチンを実行する場合は、コルーチンに2つ以上の引数を持たせることができます。

サンプル
void Start () {
    StartCoroutine (Sample(5, 0.5f));
}

private IEnumerator Sample(int num, float interval) {
    for (int i = 0; i < num; i++) {
        Debug.Log ("i:" + i);
        yield return new WaitForSeconds (interval);
    }
}

 

コルーチンの中で別のコルーチンを実行

次のように書くことで、コルーチン内で別のコルーチンを実行できます。
このとき、コルーチン内で実行したコルーチンが終了するまで、呼び出し元のコルーチンの処理は中断します。
yield return StartCoroutine (…);

サンプル
void Start () {
    StartCoroutine ("Sample1");
}

private IEnumerator Sample1() {
    for (int i = 0; i < 5; i++) {
        Debug.Log ("Sample1 i:" + i);

        // 別のコルーチンを実行して終わるまで待つ  
        yield return StartCoroutine ("Sample2");
    }
}

private IEnumerator Sample2() {
    for (int i = 0; i < 3; i++) {
        Debug.Log ("Sample2 i:" + i);
        yield return new WaitForSeconds (1f);
    }
}

 

コルーチン内で別クラスのコルーチンを実行

StartCoroutineの引数内でコルーチンを呼び出すことで、別クラスのコルーチンを実行することができます。

サンプル
public class Test2 {
    public IEnumerator Sample() {
        for (int i = 0; i < 3; i++) {
            Debug.Log ("Test2 Sample:" + i);
            yield return new WaitForSeconds (1f);
        }
    }
}
void Start () {
    StartCoroutine ("Sample");
}

private IEnumerator Sample() {
    // Test2.Sample()を実行して、それが終わるまで待つ  
    Test2 test2 = new Test2 ();
    yield return StartCoroutine (test2.Sample());

    Debug.Log ("End");
}

 

コルーチンの外部からコルーチンを終了

StopCoroutineによって、実行中のコルーチンを終了させることができます。

サンプル
void Start () {
    StartCoroutine ("Sample");
}

void Update () {
    // 「1」が押されたら「Sample」コルーチンを終了  
    if (Input.GetKey (KeyCode.Alpha1)) {
        StopCoroutine ("Sample");
    }
}

private IEnumerator Sample() {
    for (int i = 0; i < 100; i++) {
        Debug.Log ("i:" + i);
        yield return new WaitForSeconds (1f);
    }
}

 

2つ以上の引数をもつコルーチンを外部から止める

2つ以上の引数をもつコルーチンは、StartCoroutineで名前を指定して実行できないので、
StopCoroutineで名前を指定して止めることができません。
この場合は次のように止めることができます。

サンプル
public class Test : MonoBehaviour {
    private IEnumerator coroutine;

    void Start () {
        coroutine = Sample (10, 0.5f);
        StartCoroutine (coroutine);
    }

    void Update () {
        // 「1」が押されたらコルーチンを終了  
        if (Input.GetKey (KeyCode.Alpha1)) {
            StopCoroutine (coroutine);
        }
    }

    private IEnumerator Sample(int num, float interval) {
        for (int i = 0; i < num; i++) {
            Debug.Log ("i:" + i);
            yield return new WaitForSeconds (interval);
        }
    }
}

 

おわりに

以上、コルーチンの処理を簡単にまとめてみました。
これだけできれば、コルーチンを使った様々な処理に対応できるかと思います。
コルーチンはかなり便利ですので、ぜひ使いこなしてください!

採用情報

ワンダープラネットでは、一緒に働く仲間を幅広い職種で募集しております。

-エンジニア
-,

© WonderPlanet Inc.