本日は UniRx の小ネタ枠です。
UniRxの DistinctUntilChanged を使って前回と異なる入力に対してのみ処理を行う方法を記事にします。
前提条件
UniRx の環境構築手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com
DistinctUntilChangedを使って前回と異なる入力に対してのみ処理を行う
DistinctUntilChanged オペレータは前回に入力された値と異なる値が入力されたときのみ通知を流します。
オペレータは前回入力された値を保持し、比較します。また前回の値がない一回目の入力値はそのまま通します。
3つのボタンのクリックイベントに対して前回と異なるボタンが押下された場合のみ通知を行う以下のサンプルスクリプトを作成しました。
・DistinctUntilChangedTest.cs
using UniRx; using UnityEngine; using UnityEngine.UI; public class DistinctUntilChangedTest : MonoBehaviour { [SerializeField] private Button alphaButton; [SerializeField] private Button betaButton; [SerializeField] private Button gammaButton; void Start() { Observable.Merge( alphaButton.OnClickAsObservable().Select(_ => "Alpha"), betaButton.OnClickAsObservable().Select(_ => "Beta"), gammaButton.OnClickAsObservable().Select(_ => "Gamma") ) .DistinctUntilChanged() // 前回押下された値と異なる値の通知がきた場合のみ通す .Subscribe(type => Debug.Log($"{type} Button Clicked !!")) .AddTo(this); } }
3つのButtonコンポーネントを設定したサンプルシーンを用意して動作を確認します。

前回と異なるボタンが押下された場合のみログ出力の処理が呼び出されることが確認できます。

それまでの全ての値と比較する
前回の値のみではなく、それまでの全ての値と比較して初回入力の値のときのみ通知を行う場合は Distinct オペレータを利用します。
・DistincTest.cs
using UniRx; using UnityEngine; using UnityEngine.UI; public class DistinctUntilChangedTest : MonoBehaviour { [SerializeField] private Button alphaButton; [SerializeField] private Button betaButton; [SerializeField] private Button gammaButton; void Start() { Observable.Merge( alphaButton.OnClickAsObservable().Select(_ => "Alpha"), betaButton.OnClickAsObservable().Select(_ => "Beta"), gammaButton.OnClickAsObservable().Select(_ => "Gamma") ) .Distinct() // 初めて押下された通知がきた場合のみ通す .Subscribe(type => Debug.Log($"{type} Button Clicked !!")) .AddTo(this); } }