UniRxでボタンを押したらコルーチン終了

  • 2
    Like
  • 0
    Comment

 UnityでStartCoroutineメソッドやCoroutine型、使っていますか?

 コルーチンを使うことで、時間を扱うコードが非常に書きやすくそして読みやすくなります。

 またコルーチンの内部で別のコルーチンを発生させることができるので、条件分岐したり繰り返したりする複雑なコルーチンも記述可能です。

 そんなコルーチンのよくある使い方はこんな感じでしょう。

using System.Collections;
using UnityEngine;

public class ResultView : MonoBehaviour
{
    /* 中略 */

    public Coroutine Show(Result result)
    {
        StartCoroutine(ShowEnumerator(result));
    }

    IEnumerator ShowEnumerator(Result result)
    {
        /*
           ここでreusltのデータをビューに表示
        */

        FadeIn();

        yield return new WaitForSeconds(3.0F);

        FadeOut();
    }

    /* 中略 */

}

 ResultViewは、Resultを引数にとるShowメソッドを持っています。Showメソッドは、フェードインし、Resultのデータを3秒間表示し、フェードアウトします。このメソッドのポイントは次の行です。

        yield return new WaitForSeconds(3.0F);

 こうすることで、フェードインが行われてから3秒後にフェードアウトが実行されます。

 さて、「3秒後」という処理を「閉じるボタンが押されたら」に変更するにはどうすればいいでしょうか?

 Unityの標準UI、uGUIはボタンのクリックに対してデリゲート(詳しくはこちら)を登録し、「ボタンが押されたときに何をするか記述する」ことは非常に簡単にできます。しかし、このようにコルーチンと組み合わせるには工夫が必要です。

 UniRxを用いれば、ボタンが押されたイベントとCoroutineを組み合わせることが可能です。

 次のコードのように、UniRxのOnClickAsObservable拡張メソッドと、Firstメソッド、そしてToYieldInstructionを用います。

    IEnumerator ShowEnumerator(Result result)
    {
        /*
           ここでreusltのデータをビューに表示
        */

        FadeIn();

        yield return closeButton
            .OnClickAsObservable()
            .First()
            .ToYieldInstruction();

        FadeOut();
    }

 ポイントはToYieldInstructionメソッドです。これを用いることで、IObserable<T>をコールーチン内で活用できます。

 「ボタンが押された」よりももっと複雑なイベント・ストリームにも、ToYieldInstructionメソッドそしてコルーチンは活躍しそうですね。