Edited at

UniRx使い始め

More than 3 years have passed since last update.


概要

UniRxを導入してみたいけど、何から手をつけたらいいか自分がわからなかったので、

自分が手をつけ始めたところをリストアップしてみました。


後始末

参照を握りっぱなしにしてしまわないように、後始末を忘れずにしましょう。

必要ない物(場合)も多いですが、以下のような処理を書いておくのが無難です。

[NonSerialized] private CompositeDisposable disposables = new CompositeDisposable();

のような変数を用意し、.Subscribe().AddTo(disposables)をすることで、

thisの破棄時にストリームのDispose()をしてくれます。

追記

また、単にGameObjectを渡すだけでもDispose()してくれるとのことです。

.Subscribe().AddTo(this.gameObject)


FromEvent

public event Action OnEvent;

というのがあった場合、

Observable.FromEvent( h=>OnEvent+=h, h=>OnEvent-=h )

でストリーム化できます。


NGUIなどのdelegate

public OnDragFinished onDragFinished;

public delegate void OnDragFinished ();

などの場合は上記の方法では登録できませんので、

delegateの型に変換してあげる必要があります。

Observable.FromEvent<UIProgressBar.OnDragFinished>(

h => ()=>h(), h => bar.onDragFinished+=h, h => bar.onDragFinished-=h
)

で変換しましょう。


値の変更を監視

ReactiveProperty<T>で実装するのが一番ですが、

既に動いているコードへの実装は難しいと思います。

そんな場合は

Component.ObserveEveryValueChanged(_=>value)

で値が変更された時のストリームになりますのでご利用ください。


Update()そのもの

Component.UpdateAsObservable()

でUpdate()がストリームになります。

using UniRx.Triggers;

しないといけない点にご注意ください。


NGUIのOnClick()など、SendMessage()で来るもの

ObservableMouseTrigger.cs を参考に以下のような形で作成

public class ObservableNGUITrigger : ObservableTriggerBase {

Subject<Unit> onClick;

void OnClick() {
if ( null != onClick ) onClick.OnNext( Unit.Default );
}

public IObservable<Unit> OnClickAsObservable() {
return onClick ?? ( onClick = new Subject<Unit>() );
}

protected override void RaiseOnCompletedOnDestroy() {
if ( null != onClick ) {
onClick.OnCompleted();
}
}
}


いつからいつまでを表す書き方

Observable.SkipUntil(開始条件).TakeUntil(終了条件)

でいつからいつまでを表すことができます。

.RepeatUntilDestroy(this)をつけることで

thisが生きている間の開始条件〜終了条件を常に監視できます。

例:this.UpdateAsObservable().SkipUntil(mouseDown).TakeUntil(mouseUp).RepeatUntilDestroy(this)

注意点

TakeUntilのチェックは常に走ります。

つまり、以下のコードは意図した通りに動かない可能性が高いです。

IObservable<bool> flag;

this.UpdateAsObservable()
// flagにtrueが流れる前に
.SkipUntil( flag.Where( x => x ) )
// falseが流れて来てしまうと購読がそこで終了してしまう
.TakeUntil( flag.Where( x => false == x ) )


デバッグ方法


  • 途中の値が見たい

    .Do(x=>Debug.Log(x))を見たい場所に挟めば出力できます。


  • Repeatされているかどうか確かめたい

    .Finally(()=>Debug.Log("finally")).Repeat()でリピートされたタイミングのログが出せます。



参考