「Unity/UniRx/値変更検知」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→配列内のデータを検知) |
|||
行44: | 行44: | ||
{ | { | ||
var sampleClient = new SampleClient(); | var sampleClient = new SampleClient(); | ||
− | |||
sampleClient.ObserveEveryValueChanged(x => x.IsCompleted) | sampleClient.ObserveEveryValueChanged(x => x.IsCompleted) | ||
+ | // .Skip(1) // 初期値を検知を飛ばしたい場合 | ||
.Subscribe(isCompleted => | .Subscribe(isCompleted => | ||
{ | { | ||
行54: | 行54: | ||
}) | }) | ||
.AddTo(gameObject); | .AddTo(gameObject); | ||
+ | // 5秒後に遅延実行 | ||
+ | Observable.Timer(System.TimeSpan.FromSeconds(5)) | ||
+ | .Subscribe(_ => { | ||
+ | sampleClient.Request(); | ||
+ | }).AddTo(gameObject); | ||
} | } | ||
} | } | ||
行75: | 行80: | ||
{ | { | ||
var sampleClient = new SampleClient(); | var sampleClient = new SampleClient(); | ||
− | |||
sampleClient.IsCompleted | sampleClient.IsCompleted | ||
.Subscribe(value => | .Subscribe(value => | ||
行83: | 行87: | ||
}) | }) | ||
.AddTo(gameObject); | .AddTo(gameObject); | ||
+ | // 5秒後に遅延実行 | ||
+ | Observable.Timer(System.TimeSpan.FromSeconds(5)) | ||
+ | .Subscribe(_ => { | ||
+ | sampleClient.Request(); | ||
+ | }).AddTo(gameObject); | ||
} | } | ||
} | } | ||
行116: | 行125: | ||
int id = 0; | int id = 0; | ||
var sampleClient = new SampleClient(); | var sampleClient = new SampleClient(); | ||
− | |||
sampleClient.ObserveEveryValueChanged(x => x.IsCompleteds) | sampleClient.ObserveEveryValueChanged(x => x.IsCompleteds) | ||
.Subscribe(isCompleteds => | .Subscribe(isCompleteds => | ||
行147: | 行155: | ||
.AddTo(gameObject); | .AddTo(gameObject); | ||
*/ | */ | ||
+ | // 5秒後に遅延実行 | ||
+ | Observable.Timer(System.TimeSpan.FromSeconds(5)) | ||
+ | .Subscribe(_ => { | ||
+ | sampleClient.Request(id); | ||
+ | }).AddTo(gameObject); | ||
} | } | ||
} | } | ||
</pre> | </pre> |
2022年3月4日 (金) 22:39時点における版
目次
値変更検知の方法
以下2つのやり方がある。
- ReactiveProperty
- ObserveEveryValueChanged
ObserveEveryValueChangedは、前フレームと今フレームの変化をフレームごとに、判断するので負荷が高いかも。あと、1フレーム内で発生した複数回の変動は検知できない。 ただ、ReactivePropertyはコードが、更新値に.valueをつけなくてはならないし、見た目が、わかりずらい。ObserveEveryValueChangedのほうが保守性が高いかも。
参考:https://qiita.com/toRisouP/items/d0d32cf674a00f3a8427
参考:https://nekogeek.jp/reactive-property-vs-observe-every-value-changed/
ObserveEveryValueChangedを使った値変更検知サンプル
IsCompletedが、trueになったときに、検知。
sampleClient.ObserveEveryValueChanged(x => x.IsCompleted) .Subscribe(isCompleted => { // 値が変更が入ると処理される if (!isCompleted) return; Debug.Log("isCompleted=" + isCompleted); Debug.Log("sampleClient.Url=" + sampleClient.Url); }) .AddTo(gameObject);
ObserveEveryValueChangedを使った全体サンプル
using UnityEngine; using UniRx; public class ChangeValueScene : MonoBehaviour { class SampleClient { public bool IsCompleted = false; public string Url = "ttp://example.com"; public void Request() { IsCompleted = true; } } void Start() { var sampleClient = new SampleClient(); sampleClient.ObserveEveryValueChanged(x => x.IsCompleted) // .Skip(1) // 初期値を検知を飛ばしたい場合 .Subscribe(isCompleted => { // 値が変更が入ると処理される if (!isCompleted) return; Debug.Log("isCompleted=" + isCompleted); Debug.Log("sampleClient.Url=" + sampleClient.Url); }) .AddTo(gameObject); // 5秒後に遅延実行 Observable.Timer(System.TimeSpan.FromSeconds(5)) .Subscribe(_ => { sampleClient.Request(); }).AddTo(gameObject); } }
ReactivePropertyを使った全体サンプル
using UnityEngine; using UniRx; public class ReactivePropertyScene : MonoBehaviour { class SampleClient { public ReactiveProperty<bool> IsCompleted = new ReactiveProperty<bool>(false); public void Request() { IsCompleted.Value = true; } } void Start() { var sampleClient = new SampleClient(); sampleClient.IsCompleted .Subscribe(value => { if (!value) return; Debug.Log("Change IsCompleted : " + value); }) .AddTo(gameObject); // 5秒後に遅延実行 Observable.Timer(System.TimeSpan.FromSeconds(5)) .Subscribe(_ => { sampleClient.Request(); }).AddTo(gameObject); } }
ObserveEveryValueChangedを使った配列内のデータを検知
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; public class ChangeValueListScene : MonoBehaviour { class SampleClient { public List<string> Urls = new List<string>(); public List<bool> IsCompleteds = new List<bool>(); public SampleClient() { Urls.Add("ttp://example.com"); Urls.Add("ttp://example2.com"); IsCompleteds.Add(false); IsCompleteds.Add(false); } public void Request(int id) { IsCompleteds[id] = true; } } void Start() { int id = 0; var sampleClient = new SampleClient(); sampleClient.ObserveEveryValueChanged(x => x.IsCompleteds) .Subscribe(isCompleteds => { // 配列の一部の値が変更が入ると処理される Debug.Log("IsCompleteds.Count=" + isCompleteds.Count); int cnt = isCompleteds.Count; for (int tmpId = 0; tmpId < cnt; tmpId++) { Debug.Log("Id=" + tmpId + " isCompleted=" + sampleClient.IsCompleteds[tmpId]); if (!sampleClient.IsCompleteds[tmpId]) return; Debug.Log("Id=" + tmpId + " sampleClient.Url=" + sampleClient.Urls[tmpId]); } }) .AddTo(gameObject); /* ngパターンでボツ // 毎フレームごとに処理されるので危険かも。 var observable = Observable.EveryUpdate() .Subscribe(_ => { Debug.Log("IsCompleteds.Count=" + sampleClient.IsCompleteds.Count); int cnt = sampleClient.IsCompleteds.Count; for (int tmpId = 0; tmpId < cnt; tmpId++) { Debug.Log("Id=" + tmpId + " isCompleted=" + sampleClient.IsCompleteds[tmpId]); if (!sampleClient.IsCompleteds[tmpId]) return; Debug.Log("Id=" + tmpId + " sampleClient.Url=" + sampleClient.Urls[tmpId]); } }) .AddTo(gameObject); */ // 5秒後に遅延実行 Observable.Timer(System.TimeSpan.FromSeconds(5)) .Subscribe(_ => { sampleClient.Request(id); }).AddTo(gameObject); } }