Blog ブログ

UniRx 解説 ObserveEveryValueChanged で簡単値監視

皆様お久しぶりです。
エンジニアの姫野です。
最近 Nintendo Switch を購入してゼルダの伝説をプレイしてました(遅)
次は Splatoon2 、楽しみです。(そういえば前回 Switch が欲しいと言っていた社員がいたような・・・)

さて、かなり間が空いてしまいましたが今回は前回チラッと話に出した ObserveEveryValueChanged を紹介しようと思います。

ReactiveProperty と比較した形で解説するので、前回の内容をまずは読んでいただくことをオススメします。
UniRx 解説 ReactiveProperty 編

それではいってみましょう!

どんな機能?

特定の値を毎フレーム監視して更新されていればその値を流すオペレータです。
int や bool 等のプリミティブな変数、更には関数の返り値にも使うことができるので、
リアクティブでないものをリアクティブにできることが特徴です。

それでは実際に使用しているところを見てみましょう。

どうでしょう?
呼び出し方は違いますが、使っている感覚は ReactiveProperty に近いものがありますね。
こうなるとどちらを使えばよいか?と迷うかもしれません。
もう少し特徴を説明していきましょう。

1 フレームに一度しか評価されない

この特徴がどのような影響を及ぼすかというと、例えば下記のような実装があったとします。

始めの例にダメージと、回復のイベント処理が追加されましたね。
もし、 同フレームにダメージと回復のイベントが発火されたらどうなるでしょう?
勘の良い方はわかると思いますが、 ObserveEveryValueChanged は値を次に流しません。
なぜなら、ダメージと回復のイベントによって変動した結果の hp を監視しているためです。
ダメージイベントによって 10 減り、回復イベントによって 10 増えた結果、つまり値が変動していないということになりますね。

hp が ReactiveProperty であれば、値が変動するタイミングで次に値を流すので、ダメージと回復両方共通知されます。
また、逆に言えば1 フレームに一度評価されることになるためパフォーマンスに少なからず影響があるという点があります。(大抵値の評価だけ行うので大した差ではありませんが)

Cold Observable である

Cold Observable は Rx について調べたことがない方は聞きなれない単語かもしれません。(詳しくは次回説明予定です!)
この特徴がどのような影響を及ぼすか簡単に説明すると、 Subscribe した数だけ ObserveEveryValueChanged に渡した関数が呼び出されます
渡した関数が重い処理だと、その分だけ処理負荷がかかることになります。

まとめ

ObserveEveryValueChanged は特定の値の更新を監視することのできるオペレータです。
ただし、似た機能を持つ ReactiveProperty とは違う特徴を持つので適宜使い分けて行く必要があるでしょう。

使い分けとしては、
ObserveEveryValueChanged は

  • 既存のライブラリに定義された変数等、リアクティブ化したくても手を加えられない場合
  • 既存の変数や関数を楽にリアクティブ化する場合

ReactiveProperty は

  • 厳密に変化に対応した処理を書きたい時

という感じになるのではないかと思います!
それでは、次回をお楽しみに!

採用情報

クラウドクリエイティブスタジオではエンジニア募集しております。
面白いゲーム、一緒に作ってみませんか?

採用情報