R3とは
UniRxと同様に、Rx機能をより幅広いプラットフォームで利用できるようにし、 async/awatiとの連携強化、一部機能更新等が行われたライブラリ。
UniRxについては、こちらに雑にまとめてる。 shiromisasami.hatenablog.com
具体的な利用パターン
一定時間内に来る同様の処理では初回だけ処理して他は無視する
using R3; using System; using UnityEngine; public class R3Test : MonoBehaviour { private Subject<(int, float)> _subject = new Subject<(int, float)>(); private int _index = 1; private float _value = 1.0f; void Start() { //Subjectの内容設定 _subject // _subjectのNextで10秒間区切りの連続のうち最初だけを通過させる .ThrottleFirst(TimeSpan.FromSeconds(10)) .Subscribe(tuple => { var (index, Value) = tuple; Debug.Log("Index:" + index + " float:" + Value + " Time:" + Time.time); }) .AddTo(this); } void Update() { _subject.OnNext((_index, _value)); ++_index; _value += 10.0f; } }
Observable内で一定時間内に来る同じ処理の初回だけ処理して他は無視する
using R3; using Cysharp.Threading.Tasks; using System; using UnityEngine; public class R3Test : MonoBehaviour { private int _index = 1; private float _value = 1.0f; void Start() { Observable.Create<(int, float)>(async (observer, ct) => { observer.OnNext((_index, _value)); ++_index; _value += 10.0f; //5秒待機 await UniTask.Delay(TimeSpan.FromSeconds(5), cancellationToken: ct); observer.OnNext((_index, _value)); ++_index; _value += 10.0f; //5秒待機 await UniTask.Delay(TimeSpan.FromSeconds(5), cancellationToken: ct); observer.OnNext((_index, _value)); observer.OnCompleted(); }) // Observable内のOnNextを10秒間区切りの連続のうち最初だけを通過させる .ThrottleFirst(TimeSpan.FromSeconds(10)) .Subscribe(tuple => { var (index, Value) = tuple; Debug.Log("Index:" + index + " float:" + Value + " Time:" + Time.time); }) .AddTo(this); } }
入力処理とそれに伴う値変化の通知
using R3; using R3.Triggers; using UnityEngine; public class R3Test : MonoBehaviour { private R3.ReactiveProperty<int> _rpInt = new(0); void Start() { //入力で値加算/減算 this.UpdateAsObservable() .Where(_ => Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.D)) .Subscribe(_ => { if (Input.GetKeyDown(KeyCode.A)) { _rpInt.Value++; } else if (Input.GetKeyDown(KeyCode.D)) { _rpInt.Value--; } }) .AddTo(this); //値変化による通知取得 _rpInt.Subscribe(value => { Debug.Log("ChangeValue:" + value); }) .AddTo(this); } }
入力処理とそれに伴う配列値変化の通知
using R3; using R3.Triggers; using UnityEngine; using System.Collections.Generic; using System.Linq; public class R3Test : MonoBehaviour { private R3.ReactiveProperty<List<int>> _rpIntList = new(new List<int>(Enumerable.Repeat(0, 10))); private int _index = 0; void Start() { this.UpdateAsObservable() .Where(_ => Input.GetKeyDown(KeyCode.A)|| Input.GetKeyDown(KeyCode.D)|| Input.GetKeyDown(KeyCode.W)|| Input.GetKeyDown(KeyCode.S)) .Subscribe(_ => { //入力によりIndexのシフトまたは値の変更 if(Input.GetKeyDown(KeyCode.W)) { _index = Mathf.Min(++_index, _rpIntList.Value.Count - 1); } if (Input.GetKeyDown(KeyCode.S)) { _index = Mathf.Max(--_index, 0); } if (Input.GetKeyDown(KeyCode.A)) { _rpIntList.Value[_index]++; } if (Input.GetKeyDown(KeyCode.D)) { _rpIntList.Value[_index]--; } //Listの中の要素変更では通知されない ※List自体の操作は通知される //通知を強制発行 _rpIntList.ForceNotify(); }) .AddTo(this); _rpIntList.Subscribe(value => { Debug.Log("ChangeValue:" + value[_index] + " Index:" + _index); }) .AddTo(this); } }