(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]


本ブログの運営者kan.kikuchiが個人で開発した新作VRゲームがもうすぐ発売です!


ReactivePropertyのSubscribe時に最初の通知を無視する方法【Unity】【UniRx】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 2019.4.17f1
UniRx - Reactive Extensions for Unity 7.1.0


はじめに

UniRxのReactivePropertyを使うと簡単に変数の変更を検知する事が出来ます。

/*SampleA*/
//変更を監視する値
private ReactiveProperty<int> _valueReactiveProperty = new ReactiveProperty<int>(0);

//ReactivePropertyのうち、IObservableだけを公開し、処理を登録できるように
public IObservable<int> Observable => _valueReactiveProperty;
 
private void Start(){
  //てきとうに値を変更
  SetValue(1);
  SetValue(1); 
  SetValue(2); 
  SetValue(2); 
  SetValue(1); 
}

//値を設定する
private void SetValue(int value){
  _valueReactiveProperty.Value = value;
}
/*SampleB*/
[SerializeField]
private SampleA _sampleA = null;
    
private void Awake(){
  //値が変更されたらログを出すように
  _sampleA.Observable.Subscribe(count => Debug.Log(count));
}
f:id:kan_kikuchi:20190316142911j:plain


しかし、その変数の変更時の処理を登録(購読?)するSubscribe時にも処理が実行されてしまいます。

/*SampleA*/
//変更を監視する値
private ReactiveProperty<int> _valueReactiveProperty = new ReactiveProperty<int>(0);
/*SampleB*/
//値が変更されたらログを出すように(ここでもすぐにログが表示される)
_sampleA.Observable.Subscribe(count => Debug.Log(count));
f:id:kan_kikuchi:20210322063823j:plain


という事で今回は、ReactivePropertyのSubscribe時に最初の通知を無視する方法の紹介です!


そもそも「UniRxやReactivePropertyがよく分からん」という方は以下の記事を参照の事。





ReactivePropertyのSubscribe時に最初の通知を無視する方法

さっそくですが、指定回数処理をスキップするSkipというメソッド

を使うと簡単に最初の通知を無視する事が出来ます。

//値が変更されたらログを出すように(最初の1回はスキップする)
_sampleA.Observable.Skip(1).Subscribe(count => Debug.Log(count));
f:id:kan_kikuchi:20210322065108j:plain


上記の例ではSubscribeする側でスキップしていますが、

IObservableを公開する側でスキップする事も可能です。

//ReactivePropertyのうち、IObservableだけを公開し、処理を登録できるように(最初の1回はスキップする)
public IObservable<int> Observable => _valueReactiveProperty.Skip(1);


ちなみにSkipLatestValueOnSubscribeというメソッドでも同様の動作になります。

//ReactivePropertyのうち、IObservableだけを公開し、処理を登録できるように(最初の1回はスキップする)
public IObservable<int> Observable => _valueReactiveProperty.SkipLatestValueOnSubscribe();