LoginSignup
26
17

More than 5 years have passed since last update.

ちょっとづつUniRx勉強 メモ

Last updated at Posted at 2015-09-25

●仕事で使うのでメモ・・・オペレーターとかストリームという考え方が難しい

■UpdateをObservableにする。

 下記サイトによればUpdateをObservableに変換する方法は3つあるらしい
 http://qiita.com/toRisouP/items/972b97367df12c3457d2

■Updateのタイミング(1フレーム毎に)Debug.Logを出力

 ●Observable.EveryUpdate()でUpdateを監視できるようにする。
 IObservable<long> updateStream = Observable.EveryUpdate();

 ●updateStreamの監視開始
 updateStream.Subscribe(next => Debug.Log("OnNext"));

■UniRx内でのObserver.cs内でのSubscribeの定義(引数1つの時)

 public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext)
  {
   return source.Subscribe(Observer.Create(onNext, Stubs.Throw, Stubs.Nop));
 }

■UpdateをObservableにして、TakeUntilでボタンが押されるまでログ出力されるようにする

(注)第2引数のOnCompleteは今のところ無意味

■ボタンがクリックされるとDebug.Logの出力がとまる

testbuttonはヒエラルキー上のボタンと紐づける事

 public Button testbutton;

 // Use this for initialization
 void Start () 
 {
  // UpdateをObservableに変換、TakeUntil~になるまで実行される 今回はボタンが押されるまで
  IObservable<long> updateStream = Observable.EveryUpdate().TakeUntil(testbutton.OnClickAsObservable());

  updateStream.Subscribe(next => Debug.Log("OnNext"), comp => Debug.Log("Comp"));
 }

■UpdateをObservableにし、ボタンが押されるとReactivePropertyで定義した数値に加算してDebug.logに表示、数値の変化に連動してテキストの表示も変更される

IntReactiveProperty textValue = new IntReactiveProperty(0);

public Button testbutton;
public Text testText;


// Use this for initialization
void Start () {

    // UpdateをObservableに変換
    IObservable<long> updateStream = Observable.EveryUpdate();
    // Updateのタイミングでクリックカウントをログに表示
    updateStream.Subscribe(
        next => Debug.Log("OnNext=" + textValue.Value.ToString())
        );

    // クリックされるとIntReactiveProperty textValueの値に加算していれるように登録。
    testbutton
            .OnClickAsObservable()
            .Do(_ => textValue.Value++)
            .Subscribe(
                _ => Debug.Log("textValue.Value=" + textValue.Value.ToString())
            );


    // textValueが変化したらテキストボックスの値も変化するよう登録
    textValue.Subscribe(
        _ => testText.text = textValue.ToString()
        );
}

■ボタンの連打を防ぐ

どの現場に行っても毎回悩まされるけど、
UniRxなら防げる、うれしい!

ThrottleFirstで最初の1回の通知を受けてから
指定TimeSpanの間、通知を遮断する。

addhitbutton.OnClickAsObservable()
.ThrottleFirst(TimeSpan.FromMilliseconds(1000))
.Subscribe
( 
_ => Debug.Log("Hit!!")
);

もう1つはいい方法かわからんけど
Throttleを使う。
Throttleは通知が集中すると最後以外を無視して
指定TimeSpan経過後、通知する。

addhitbutton.OnClickAsObservable()
.Throttle(TimeSpan.FromMilliseconds(250))
.Subscribe
( 
_ => Debug.Log("Hit!!")
);

■Androidのハードウェア戻るボタンの連打を防ぐ(まだ実機で試してません)

これも本当に毎回悩まされる。
でもUniRxだったら防げるはず。

IObservable<Unit> keydown = this.UpdateAsObservable();

keydown.Where(
BackKey => Input.GetKey(KeyCode.Escape))
.ThrottleFirst(TimeSpan.FromMilliseconds(1000))
.Subscribe(
Key => Debug.Log("Android BackKey")
);

■Intervalを使用して一定間隔でダウンロード中メッセージと進捗の%を表示

※Intervalは無限にプッシュし続けるのでWhere句で制御

//0.2秒ごとに100回までプッシュ
Observable.Interval(TimeSpan.FromSeconds(0.2f))
    .Where(_ => this.progressCount.Value <= 100)
    .Subscribe
(_ =>
    {
        if ((DownloadMessage.text.Length -
            DownloadMessage.text.Replace("・", "").Length) >= 3)
        {
            DownloadMessage.text = "リソースダウンロード中";
        }
        else
        {
            DownloadMessage.text =
                DownloadMessage.text + "・";
        }

        this.progressCount.Value++;
        if (this.progressCount.Value <= 100)
        {
            DownloadProgress.text = this.progressCount.ToString() + " %";
        }
        UnityEngine.Debug.Log("progressCount=" + progressCount.ToString());
    }
)
.AddTo(this.gameObject);

// 100%になったらシーン移動
progressCount
    .Where(num => num > 100)
    .First()
    .Subscribe(_ =>
    {
        シーン移動処理
    })
    .AddTo(this.gameObject);


26
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
17