はじめに
この記事では UniRx の Where() と ThrottleFirst() の使用方法をメモしておきます。
Where() と ThrottleFirst() について解説する前にまずは基礎となるメソッドである ~AsObservable() と Subscribe() について確認しておきます。
メソッド名 | 概要 |
~AsObservable() | 元のメソッド(「As」の前の名前のメソッド)と同じ動きをする Observable です。 例えば ~AsObservable() を使った処理を Start() の中に記述することで、Start() を見るだけで全体の処理がわかるようになるなどのメリットがあります。 |
Subscribe() | 購読(監視)相手を登録してメッセージ(通知)を伝達することができます。 |
では次は Where() と ThrottleFirst() についてです。
オペレーター名 | 概要 |
Where() | メッセージを受け取る条件を設定できます。 個人的には Subscribe() の中の処理が1つだけのときに使用するのが望ましいかと思っています。 |
ThrottleFirst() | 1度メッセージを受け取った後に再びメッセージを受け取るまでの待機時間(2回目以降のメッセージを無視する時間)を設定できます。 主にボタンやキーの入力などで使用します。 |
使用方法
では具体的な使用方法を見ていきます。
以下のコードでは Sample というクラスで GameObject 型の objSample 変数と Button 型の btnSample 変数を宣言しています。
そして Start() の中で objSample の OnCollisionEnterAsObservable() や btnSample の OnClickAsObservable()、自身の OnDestroyAsObservable() と UpdateAsObservable() などを購読しています。
具体的な処理内容はコメントの通りです。
using UniRx;
using UniRx.Triggers;
using UnityEngine;
public class Sample : MonoBehaviour
{
[SerializeField]
private GameObject objSample;
[SerializeField]
private Button btnSample;
private void Start()
{
// objSample の OnCollisionEnter() を Observable に変換して購読する
//(監視を開始する)
objSample.OnCollisionEnterAsObservable()
//他のコライダーに触れたら Obsevable からメッセージが発行されて、
//それを collision 変数として渡し、接触相手の GameObject 名を表示する
.Subscribe(collision => Debug.Log(collision.gameObject.name))
//自身が消えたら講読をやめる
.AddTo(this);
// btnSample の UnityEvent である onClick を Observable に変換して購読する
//(監視を開始する)
btnSample.OnClickAsObservable()
// btnSample が押されたら Observable からメッセージが発行されるが、
//2回目以降のメッセージを2.0秒間無視する
.ThrottleFirst(System.TimeSpan.FromSeconds(2.0f))
// Observable から発行されたメッセージを受け取って「押された」と表示する
.Subscribe(_ => Debug.Log("押された"))
//自身が消えたら講読をやめる
.AddTo(this);
//自身の OnDestroy() を Observable に変換して購読する
//(監視を開始する)
this.OnDestroyAsObservable()
//自身が消えたら Obsevable からメッセージが発行されて、
//それを受け取って「破棄された」と表示する
.Subscribe(_ => Debug.Log("破棄された"));
//自身の Update() を Observable に変換して購読する
//(監視を開始する)
this.UpdateAsObservable()
// Observable からメッセージが毎フレーム発行されるが、
//スペースキーが押されていない間はそれらのメッセージを無視する
.Where(_ => Input.GetKey(KeyCode.Space))
//2回目以降のメッセージを2.0秒間無視する
.ThrottleFirst(System.TimeSpan.FromSeconds(2.0f))
// Observable から発行されたメッセージを受け取って「ジャンプ」と表示する
.Subscribe(_ => Debug.Log("ジャンプ"))
//自身が消えたら講読をやめる
.AddTo(this);
}
}