今回のエンジニアブログは大橋が担当します。
初登場です。よろしくお願いします。
さて、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); } } }
おわりに
以上、コルーチンの処理を簡単にまとめてみました。
これだけできれば、コルーチンを使った様々な処理に対応できるかと思います。
コルーチンはかなり便利ですので、ぜひ使いこなしてください!