【Unity】UniRxを覚える(2)
前回の記事。
UniRxを覚える(1)で学んだ、
Subjectを定義して、OnNextとして、Subscribeに到達
という流れをストリームと呼びます。
IObservableのSubscribeはIDisposableというインターフェースで実装されています。
これはリソースの開放を行うためのもので、
Dispose()のみ定義されています。
SubjectでDisposeを実行すると、ストリームの購読を終了することができます。
/// <summary> /// UniRx Subject。 /// </summary> public Subject<string> subject = new Subject<string>(); void Awake() { // UniRx Subject登録。 subject .Subscribe( message => { Debug.Log(message); }, () => { Debug.Log("Completed"); } ); } void Start() { // UniRx Subject呼び出し。 subject.OnNext("UniRx Hello!"); subject.Dispose(); subject.OnNext("UniRx Hello!"); subject.OnCompleted(); }
Disposeのあとの処理は呼び出されません。
Subjectが破棄されればストリームも全て破棄されます。
Subjectが残っていればストリームは動き続けます。
ストリームは使い終わったら必ずDisposeを呼ぶ
またはOnCompletedを発行するようにする。
AddTo
AddToを実装すれば、GameObjectが破棄されたタイミングで、
自動的にDisposeを行ってくれます。
// UniRx Subject登録。 subject .Subscribe( message => { Debug.Log(message); }, () => { Debug.Log("Completed"); } ).AddTo(gameObject);
Subject
自由にイベントを発行したいとき。
ReactiveProperty
変数にSubjectの機能をくっつけたもの。
var reactiveProperty = new ReactiveProperty<string>("sample"); reactiveProperty.Value = "Hello"; reactiveProperty.Subscribe(e => Debug.Log(e)); reactiveProperty.Value = "hello";
ReactiveCollection
状態の変化を通知する機能が内蔵されたList< T >
var reactiveCollection = new ReactiveCollection<int>(); reactiveCollection .ObserveAdd() .Subscribe(x => { Debug.Log("Add Index: " + x.Index + " Value: " + x.Value); }); reactiveCollection .ObserveRemove() .Subscribe(x => { Debug.Log("Remove Index:" + x.Index + " Value: " + x.Value); }); reactiveCollection.Add(1); reactiveCollection.Add(2); reactiveCollection.Remove(2);
Observable.Create
自由に値を発行するストリームを作ることができるファクトリメソッド。
Observable.Create<int>(ob => { ob.OnNext(1); ob.OnCompleted(); return Disposable.Create(() => {}); }).Subscribe(e => Debug.Log(e));
Observable.Start
別スレッドで実行して結果を一つだけ発行するファクトリメソッド。
非同期で走らせ結果が出たら通知。
Observable.Start(() => { var count = 0; for(var idx = 0; idx < 10000; ++idx) { count += idx; } return count; }) .ObserveOnMainThread() .Subscribe(e => Debug.Log(e)); Debug.Log("mainThread");
mainThreadの文字列が先に発行される。
Observable.Timer/TimerFrame
一定時間後にメッセージを発行するファクトリメソッド。
実時間はTimer、フレーム数での指定はTimerFrame
Observable.Timer(System.TimeSpan.FromSeconds(3)) .Subscribe(e => Debug.Log("elapsed 3sec")); Observable.Timer(System.TimeSpan.FromSeconds(3), System.TimeSpan.FromSeconds(1)) .Subscribe(e => Debug.Log("elapsed 3sec and repeat 1sec")) .AddTo(gameObject);
第一引数に発行されるまでのTimeSpan、第二引数に繰り返し発行するTimeSpanを指定できる。
Observable.EveryUpdate
Update時に通知してくれるストリームソース。
停止しない限りシーンをまたいでも動き続けます。
Observable.EveryUpdate().Subscribe(e => Debug.Log("every update"));
UniRx.Triggers
UnityのコールバックイベントをUniRxのIObservableに変換してくれる。
this.FixedUpdateAsObservable() .Subscribe(e => Debug.Log("fixed update"));
uGUIイベントのストリームソース
クリックイベント
[SerializeField] Button button = null; button.OnClickAsObservable().Subscribe(e => Debug.Log("onclick"));
(3)に続きます。
sunagimo-app.hatenablog.com