EveryValueChanged
1. 概要
EveryValueChanged は、対象オブジェクトのプロパティをフレームごとにポーリングし、値が変化したときにその新しい値を発行するファクトリメソッドです。
購読時に現在の値を 1 回発行し、その後は前回値と異なる値になったフレームで新しい値を発行します。監視は CancellationToken のキャンセル、または購読の破棄によって終了します。
注意:
TSourceは参照型(class)である必要があります。
2. シグネチャ
基本(既定の FrameProvider)
public static Observable<TProperty> EveryValueChanged<TSource, TProperty>(TSource source, Func<TSource, TProperty> propertySelector, CancellationToken cancellationToken = default)
where TSource : class既定の FrameProvider(ObservableSystem.DefaultFrameProvider)を使って毎フレーム値をチェックします。
Observable.EveryValueChanged(player, p => p.Health)FrameProvider 指定
public static Observable<TProperty> EveryValueChanged<TSource, TProperty>(TSource source, Func<TSource, TProperty> propertySelector, FrameProvider frameProvider, CancellationToken cancellationToken = default)
where TSource : classカスタムの FrameProvider を指定して、ポーリングのタイミングを制御します。
Observable.EveryValueChanged(player, p => p.Health, customFrameProvider)EqualityComparer 指定
public static Observable<TProperty> EveryValueChanged<TSource, TProperty>(TSource source, Func<TSource, TProperty> propertySelector, EqualityComparer<TProperty> equalityComparer, CancellationToken cancellationToken = default)
where TSource : class値の比較に使用する EqualityComparer<TProperty> を指定します。既定では EqualityComparer<TProperty>.Default が使われます。
FrameProvider + EqualityComparer 指定
public static Observable<TProperty> EveryValueChanged<TSource, TProperty>(TSource source, Func<TSource, TProperty> propertySelector, FrameProvider frameProvider, EqualityComparer<TProperty> equalityComparer, CancellationToken cancellationToken = default)
where TSource : classFrameProvider と EqualityComparer の両方を指定する完全版です。
オーバーロードの使い分け
| オーバーロード | 使う場面 |
|---|---|
EveryValueChanged(source, selector) | 既定設定でプロパティ変化を監視する |
... , frameProvider) | ポーリングのフレームプロバイダーをカスタマイズしたい |
... , equalityComparer) | 値の等価比較をカスタマイズしたい |
... , frameProvider, equalityComparer) | 両方をカスタマイズしたい |
3. マーブルダイアグラム
購読直後に現在の値が発行されます。その後は毎フレームプロパティの値がチェックされ、前回の値と異なる場合のみ新しい値が発行されます。CancellationToken がキャンセルされるとシーケンスが完了します。
4. サンプルコード
using R3;
// === ゲームオブジェクトのヘルス変化を監視 ===
var player = new Player { Health = 100 };
Observable.EveryValueChanged(player, p => p.Health)
.Subscribe(hp => Console.WriteLine($"HP: {hp}"));
// Health が変化するたびに出力:
// HP: 100(初回値)
// HP: 80(ダメージを受けた)
// HP: 50(さらにダメージ)
// === Transform の位置変化を監視(Unity 向け) ===
// Observable.EveryValueChanged(transform, t => t.position)
// .Subscribe(pos => Debug.Log($"位置: {pos}"));
// === カスタム EqualityComparer を使用 ===
var sensor = new TemperatureSensor();
Observable.EveryValueChanged(
sensor,
s => s.Temperature,
EqualityComparer<double>.Create(
(a, b) => Math.Abs(a - b) < 0.5, // 0.5 度未満の変化は無視
x => x.GetHashCode()))
.Subscribe(temp => Console.WriteLine($"温度: {temp:F1}°C"));5. 補足
ObservePropertyChanged との違い
ObservePropertyChanged は INotifyPropertyChanged インターフェースを実装したオブジェクトに対して、プロパティ変更イベント(プッシュ型)で値の変化を検知します。イベント駆動のため毎フレームの比較コストが発生しません。
一方、EveryValueChanged は毎フレームのポーリング(プル型)で値を監視するため、INotifyPropertyChanged を実装していない任意のクラスに使用できます。ゲームオブジェクトや外部ライブラリの型など、変更通知の仕組みを持たないオブジェクトの監視に適しています。