❤️

【UniRx】BoolReactivePropertyの値の更新について

2023/07/24に公開

動機

  1. UniRx/UniTaskを使い始めて随分経ったが、未だに体系だった知識が自分の中に
    構築されていない
  2. 知識を整理することで改善の糸口としたい
  3. どうせまとめるならば公開したほうが良いだろう

個人的なメモ書きですので、気をつけてご参照くださいませ。

本文

UniRxのBoolReacitivePropertyには値の変更方法が二種類ある。一つはインスタンスからValueプロパティにアクセスし、その値を書き換える手法。もう一つはインスタンスからSetValueAndForceNotify(bool)メソッドにアクセスし、値を書き換える手法。
どう異なるのだろうか?

BoolReactiveProperty _isBRP = new BoolReactiveProperty(false);

void Start()
{
	// Valueプロパティにアクセスし値を書き換える
	_isBRP.Value = true; 
	
	// SetValueAndForceNotifyを利用して値を書き換える
	_isBRP.SetValueAndForceNotify(false); 
}

それぞれの違いは、通知の発行され方にある。

Valueプロパティ

Valueプロパティに値が代入された場合、通知は前回のValueから値が変更されるときのみ発行される。具体的には、_isBRP.Valuefalseからtrueに変わった時、またはtrueからfalseに変わった時のみ発行される。

以下から確認できる。

using UnityEngine;
using UniRx;

public class TestBRP: MonoBehaviour
{
    BoolReactiveProperty _isBRP = new BoolReactiveProperty();
    int _counterBRP = 0;

    private void Start()
    {
        _isBRP.Subscribe(_ =>
        {
            _counterBRP++;
            Debug.Log($"<color=cyan> _isBRP は{_isBRP.Value}として呼び出されました。</color>");
            Debug.Log($"<color=cyan> 本呼び出しは{_counterBRP}回目です。</color>");
        });
    }

    private void Update()
    { 
        if(Input.GetMouseButton(0))
        {
            _isBRP.Value = true;
        }
        else
        {
            _isBRP.Value = false;
        }
    }
}

実行後、マウス操作なし

クリック一回目、長押し

  • 本来長押ししている最中、常にValueには値が代入されている
  • しかし、代入された値が前回と同じ値であるために、通知が行われない

クリック一回目、指を離す

  • 値の変更が行われたので通知が発行された

本例からも理解できたと思うが、BoolReacitvePropertyをインスタンス化する際、初期値の設定でも通知は発行されることには注意が必要だろう。

SetValueAndForceNotify

SetValueAndForceNotify()メソッドが用いられた場合、前回のValueの値が何であれ必ず
通知を行う
。現在のValueの値を気にせず通知を行うことができるメソッドとなっている。

以下から確認できる。

using UnityEngine;
using UniRx;

public class TestBRP: MonoBehaviour
{
    BoolReactiveProperty _isBRP = new BoolReactiveProperty();
    int _counterBRP = 0;

    private void Start()
    {
        _isBRP.Subscribe(_ =>
        {
            _counterBRP++;
            Debug.Log($"<color=cyan> _isBRP は{_isBRP.Value}として呼び出されました。</color>");
            Debug.Log($"<color=cyan> 本呼び出しは{_counterBRP}回目です。</color>");
        });
    }

    private void Update()
    { 
        if(Input.GetMouseButton(0))
        {
            _isBRP.SetValueAndForceNotify(true);
        }
        else
        {
            _isBRP.SetValueAndForceNotify(false);
        }
    }
}

実行後、マウス操作なし

  • SetValueAndForceNotify(false)によって通知が送られ続けているのがわかる
  • もちろん、クリックし続けるとこの通知がtrueのものに変わる

実行後、クリック長押し

Discussion