ちょっとづつUniRx勉強　メモ

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

## ■UpdateをObservableにする。

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

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

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


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


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

```
　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でボタンが押されるまでログ出力されるようにする

（注）第２引数の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で最初の１回の通知を受けてから
指定TimeSpanの間、通知を遮断する。

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


もう１つはいい方法かわからんけど
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秒ごとに１００回までプッシュ
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);


```