複数の IEnumerator
を待つ場合は以下のような処理を書く必要があり面倒だったので
手軽に複数の IEnumerator
を待てないかと思い作成しました
private void WaitAll(Action action) { var end = 0; void End() { if (++end >= 2) { action.Invoke(); // End Call } } StartCoroutine(Wait1(End)); StartCoroutine(Wait2(End)); } private IEnumerator Wait1(Action end) { yield return new WaitForSeconds(3f); end.Invoke(); } private IEnumerator Wait2(Action end) { yield return new WaitForSeconds(1f); end.Invoke(); }
複数を待つコード
引数の IEnumerator
を内部で StartCoroutine してすべての終了をチェックすることで複数を待てるようにしました
また、 よく使う YieldInstruction
に関しても利用できるように対応してみました
params に両方利用できれば良かったのですが、厳しかったので別々で利用する形になりました
public IEnumerator WaitAll(params YieldInstruction[] yis) { var endCount = 0; foreach (var yi in yis) StartCoroutine(PlayCoroutine(yi, () => endCount++)); yield return new WaitUntil(() => endCount >= yis.Length); } public IEnumerator WaitAll(params IEnumerator[] enumerators) { var endCount = 0; foreach (var enumerator in enumerators) StartCoroutine(PlayCoroutine(enumerator, () => endCount++)); yield return new WaitUntil(() => endCount >= enumerators.Length); } public void WaitAll(Action end, params YieldInstruction[] yis) { var endCount = 0; foreach (var yi in yis) { StartCoroutine(PlayCoroutine(yi, () => { if (++endCount >= yis.Length) end?.Invoke(); })); } } public void WaitAll(Action end, params IEnumerator[] enumerators) { var endCount = 0; foreach (var enumerator in enumerators) { StartCoroutine(PlayCoroutine(enumerator, () => { if (++endCount >= enumerators.Length) end?.Invoke(); })); } } private IEnumerator PlayCoroutine(YieldInstruction yi, Action end) { yield return yi; end?.Invoke(); } private IEnumerator PlayCoroutine(IEnumerator enumerator, Action end) { yield return enumerator; end?.Invoke(); }
サンプル
IEnumerator
を複数利用した場合
private IEnumerator Test() { yield return WaitAll(A(5f), B(3f)); } private IEnumerator A(float seconds) { yield return new WaitForSeconds(seconds); } private IEnumerator B(float seconds) { yield return new WaitForSeconds(seconds); }
YieldInstruction
を複数利用した場合
private IEnumerator Test() { var a = new WaitForSeconds(1f); var b = new WaitForSeconds(3f); yield return WaitAll(a, b); }
IEnumerator
と YieldInstruction
を利用した場合
WaitAll の戻り値が IEnumerator
なので、それを利用して一緒に呼び出します
見た目が少し悪いのは仕方なし
private IEnumerator Test() { var a = new WaitForSeconds(1f); var b = new WaitForSeconds(3f); yield return WaitAll(WaitAll(a, b), A(5f)); } private IEnumerator A(float seconds) { yield return new WaitForSeconds(seconds); }