読者です 読者をやめる 読者になる 読者になる

WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

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

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

さて、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);  
        }  
    }  
}  

 

おわりに

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