さけのさかなのブログ

同人ゲーム開発やってます。Unity使ったりする。

コルーチンを復帰させる

問題

 Unityのコルーチンは、オブジェクトがinactiveになると停止し、その後activeにしても動き出さない。
 これをなんとかして、activeにしたら再びコルーチンが動き出すようにしたい。

コード


public class ResumeTest : MonoBehaviour
{
    IEnumerator routine;

    void Start()
    {
        routine = Process();
        StartCoroutine(routine);
    }

    void OnEnable()
    {
        if (routine != null)
        {
            StartCoroutine(routine);
        }
    }

    IEnumerator Process()
    {
        int i=0;
        while(true)
        {
            Debug.Log(i);
            ++i;
            yield return new WaitForSeconds(0.5f);
        }
    }
}

 インスペクタでアクティブ/非アクティブを切り替えてチェックしてみると、続きからループが始まるようになっているのがわかる。

 要するに、コルーチンの開始時にIEnumratorを取っておけば、あとはOnEnableのタイミングでStartCoroutine()に渡してやれば復帰できるというわけ。

ちなみに

 コルーチンの中でコルーチンを呼んでいる場合だと、ちょっと面倒。

public class ResumeTest : MonoBehaviour
{
    IEnumerator routine;

    void Start()
    {
        routine = Process();
        StartCoroutine(routine);
    }

    void OnEnable()
    {
        if (routine != null)
        {
            StartCoroutine(routine);
        }
    }

    IEnumerator Process()
    {
        int i = 0;
        while (true)
        {
            ++i;

            var subroutine = SubProcess(i);
            yield return StartCoroutine(subroutine);
            // 復帰処理
            while (subroutine.MoveNext())
            {
                yield return StartCoroutine(subroutine);
            }
        }
    }

    IEnumerator SubProcess(int a)
    {
        for(int i = 0 ; i< 10 ; ++i)
        {
            Debug.Log(a.ToString() + ", " + i.ToString());
            yield return new WaitForSeconds(0.5f);
        }
    }
}
   

 外のコルーチンを復帰させただけだと、中で呼んでるコルーチンはまだ動かない。なので、コルーチンの中にコルーチンを復帰させる処理を書かなくてはならない。

 中断したかどうかは、つまり処理が完了してるかどうかなので、MoveNextで判断することができる。
 whileになっているのは、SubProcess処理中に何度もinactiveになるケースがあるため。