Help us understand the problem. What is going on with this article?

【UniRx】ObserveEveryValueChangedでフレーム間での値の変動を監視する

More than 3 years have passed since last update.

UniRxについての記事のまとめはこちら


先日投稿した「未来のプログラミング技術をUnityで -UniRx-」において、値の変動を監視をUniRxで行う方法を紹介しました。
ですが、UniRxの3/22の更新分で「ObserveEveryValueChanged」という機能が修正され、値の変動の監視がとても簡単にできるようになったので使い方を紹介したいと思います。

ObserveEveryValueChanged()

ObserveEveryValueChangedは全クラスに対する拡張メソッドとして定義されており、以下の様な特徴があります。

  • 任意のクラスオブジェクトに対して使用できる(ただしUnityEngine.Object以外に適用するのは安全ではない
  • 対象のインスタンスオブジェクトのプロパティ値(プロパティに限らずに値を返すものなら何でも)が前フレームと比較して変化していた際にその値をOnNextに流す
  • 1フレーム内で発生した複数回の変動は検知できず、前フレームと今フレームの変化のみ検知できる
  • メッセージが流れるタイミングは厳密にはUpdate()ではなくコルーチンの実行タイミングとなる(参考)
  • 対象がUnityEngine.Objectの派生オブジェクトだった場合、Destroy時にOnCompletedが飛ぶ
  • MonoBehaviour以外の場所でも使用することができる

使用例)CharacterController.isGroundedを監視する

ObserveEveryValueChangedを使った例

//キャラクタが着地した瞬間の検知
characterController
    .ObserveEveryValueChanged(x => x.isGrounded)
    .Where(x => x)
    .Subscribe(_ => Debug.Log("OnGrounded!"));
比較)ObserveEveryValueChangedを使わない例(ObservableMonoBehaviourを継承している場合)
UpdateAsObservable()
    .Select(_ => characterController.isGrounded)
    .DistinctUntilChanged()
    .Where(x => x)
    .Subscribe(_ => Debug.Log("OnGrounded!"));

UpdateAsObservable().Select(_ => characterController.isGrounded).DistinctUntilChanged() の部分がなくなり、スッキリ書くことができました。

まとめ

ObserveEveryValueChanged()を使うことで「毎フレーム値の変動を監視して何かしたい」といったことがより簡潔に記述できるようになりました。
ただし、UnityEngine.Object以外のclassオブジェクトに対してObserveEveryValueChangedを使用すると手動でオブジェクト破棄時にSubscribeのDisposeを行う必要が出てくるので注意が必要です。
(追記:3/23に修正されてPOCOなインスタンスオブジェクトについても破棄時に勝手にOnCompletedが飛ぶようになったようです!)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした