UnityのCoroutine的なものを自前で実装する
Coroutine
コルーチンはこんな感じで使えるやつだ
void Awake() { StartCoroutine(Test()); } IEnumerator Test1() { DoSomething(); yield return null; Hoge(); yield break; }
コルーチンのネストもできて
void Awake() { StartCoroutine(Test2()) } IEnumerator Test2() { Debug.Log("1"); yield return null; Debug.Log("2"); yield return StartCoroutine(Test3()) Debug.Log("3"); yield break; } IEnumerator Test3() { Debug.Log("A"); yield return null; Debug.Log("B"); yield break; }
こんな感じにすると1, 2, A, B, 3の順で出力される(たぶん)。
Coroutineの問題点
この記事の目的はあくまで「実装してみよう!!」というものであり問題点を指摘することが目的ではないが、実装への動機づけのために言及しておく。
イテレータから何が返ってくるかわからな
イテレータをネストしているとき、つまりTest2関数の中でTest3関数を呼んでいるようなことをしているときの話である。
例えばTest3の中でのある処理が成功したか失敗したかをTest2で知る必要があったとしよう。
それを知るにはTest3の最後にyield return false
などとしてやればよい。
しかしさらにTest3の中からさらにTest4へとネストしたい場合、yield return StartCoroutine(Test4())
ともしてやらなければならない。
こうなった場合、関数の返り値の型をIEnumerator<bool>
などと指定することは不可能となり、単にIEnumerator
と書かなければならなくなる。
そうするともはやイテレータから何が返ってくるのかがわからなくなり、あるいは無法地帯のような状況になってしまうかもしれない。
そうならないためにも、UnityにおけるCoroutineのようなものを自前で用意しようということなのである。
実装
というわけで、自前で実装してみたのがこちらになります。
gist.github.com
こうしておくとイテレータが何返してくるのかわかって安心だよねーという話でした。
意外と簡単に実装できますね。
使い方
こんな感じで使うよー\(^o^)/
private Iterator iterator; private bool flag = false; void Awake() { iterator = new Iterator(); } void Update() { iterator.Progress(); } IEnumerator<IteratorResult> Hoge() { yield return IteratorResult.Continue; yield return IteratorResult.Nest(Fuga()); yield return IteratorResult.Completed; } IEnumerator<IteratorResult> Fuga() { yield return IteratorResult.Continue; if(!flag) { yield return IteratorResult.Canceled; yield break; } yield return IteratorResult.Completed; }
まとめ
UnityのCoroutineを自前で実装してみたよ! 他にいい方法があったら教えてくり!!