まきゼミ技事録!

とあるゼミのプログラマー達が送る技術ブログのようなもの

Unityコルーチンについて

さんかくです。(/・ω・)/
今日はUnityコルーチンについて紹介したいと思います。

コルーチンとは

コルーチン(英: co-routine)とはプログラミングの構造の一種。 サブルーチンがエントリーからリターンまでを一つの処理単位とするのに対し、コルーチンはいったん処理を中断した後、続きから処理を再開できる。
Wikipediaからの引用)

ということなのですが、Unityでのコルーチンとは
「いったん処理を中断した後、続きから処理を再開できる」
と考えて良いと思います。
何秒後に再び実行させるなどの処理をさせることができます。

どのような場合に使うか
  • 321のカウントダウンを毎回Updateで計算させずに実行したい。
  • 周囲に敵がいないか探索する場合、10毎秒に探索させることにより余計な呼び出しを減らす。
  • Update関数に入れずにコルーチンを使用することによって、Update関数をきれいにすることができる。
カウントダウンの表示をコルーチンで実装

まずはコルーチンを使わない場合です。

using UnityEngine;
using UnityEngine.UI;
public class Countdown : MonoBehaviour
{
    [SerializeField]
    Text t = null;
    float totalTime = 0.0f;
    private void Start()
    {
        t.text = "3";
    }
    void Update()
    {
        totalTime += Time.deltaTime;
        if (totalTime >= 3)
            t.gameObject.SetActive(false);
        else if (totalTime >= 2)
            t.text = "1";
        else if (totalTime >= 1)
            t.text = "2";
    }
}

次にコルーチンを使った場合↓

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Countdown : MonoBehaviour
{
    [SerializeField]
    Text t = null;
    private void Start()
    {
        StartCoroutine(UpdateCountdown());
        //メソッド名でもOK
        //StartCoroutine("UpdateCountdown"); 
    }
    IEnumerator UpdateCountdown()
    {
        t.text = "3";
        yield return new WaitForSeconds(1);
        t.text = "2";
        yield return new WaitForSeconds(1);
        t.text = "1";
        yield return new WaitForSeconds(1);
        t.gameObject.SetActive(false);
    }
}

Update関数を無くすことができたり、秒数を持つ機能のおかげで毎回合計時間を取得していたtotalTime変数、他にも毎回時間が指定時間経過したかの計算を無くすことができました。
コルーチンを使うことにより、綺麗にわかりやすくコードを記述することができます。

コード解説
using System.Collections;

コルーチンを使用する際に必要です。

IEnumerator UpdateCountdown()
{ 
...省略
}

コルーチンにはIEnumerator を返す関数を作ります。
IEnumerableでは無いです。よく間違えます(・ω・)

Debug.Log("1");
yield return new WaitForSeconds (1);  //1秒後に再開
Debug.Log("2");
yield return null;//次のフレームで再開
Debug.Log("3");
yield break;//コルーチンを途中で終了
Debug.Log("4");
// yield return StartCoroutine(コルーチン名);//コルーチンの中で別のコルーチンを実行することもできます

基本的にコメントに書いてある通りのことができます。
今回はyield return new WaitForSeconds (1);を使っていたので、
文字を変更→一秒待機→文字を変更・・・
をわかりやすく記述することができました。
ちなみに上の例の結果は下のようになります。

1
2
3

yield break;で途中で終了したのでDebug.Log("4");は実行されません。

StartCoroutine(UpdateCountdown());
StartCoroutine(”UpdateCountdown”);
StartCoroutine("コルーチン名",引数1);//引数は一つまで
StartCoroutine(コルーチン名(引数1,引数2));

コルーチンの実行にはStartCoroutineを使用します。
コルーチン名をstringで入れることもできます。
stringの場合は引数を一つしか持たせることができません。

終わりに

コルーチンは便利ですが、しっかり管理しないと思わぬバグなどを起こしたりもするので気をつけてください。

参考サイト

docs.unity3d.com
使用するときお世話になりました。↓
developer.wonderpla.net