1. 程式人生 > >UniRx第一季學習(五) ------ 操作符Merge/Coroutine/WhenAll/OnCompleted/Start

UniRx第一季學習(五) ------ 操作符Merge/Coroutine/WhenAll/OnCompleted/Start

課程地址 : http://www.sikiedu.com/course/271

涼鞋大大的,可以的話大家多支援一波~


一.Merge

UniRx 可以開啟兩個或多個事件流。並使⽤ Merge 進⾏事件流的合併,比如實現⿏標左鍵或右鍵點選時都會進⾏處理:

var leftMouseClickStream = Observable.EveryUpdate().Where(_ => 
Input.GetMouseButtonDown(0));
var rightMouseClickStream = Observable.EveryUpdate().Where(_ => 
Input.GetMouseButtonDown(1));

Observable.Merge(leftMouseClickStream, rightMouseClickStream)
.Subscribe(_ => 
{
     // do something
});

二.Coroutine 

UniRx 對 Unity 的 Coroutine 也提供⽀持,可以將⼀個 Coroutine 轉化為事件源(Observable)。

 public class Observable2YieldExample : MonoBehaviour
    {
        IEnumerator Delay1Second()
        {
            yield return Observable.Timer(TimeSpan.FromSeconds(1.0f)).ToYieldInstruction();
            Debug.Log("delay 1 seconds");
        }

        void Start()
        {
            StartCoroutine(Delay1Second());
        }
    }

三.WhenAll

WhenAll 和 Merge 是同類型的,是處理多個流的操作符,就是當所有的事件流都結束,就會觸發 Subscribe 註冊的回撥。

1.Coroutine的並行操作

 public class CoroutineSpawnExample : MonoBehaviour
    {
        IEnumerator A()
        {
            yield return new WaitForSeconds(1.0f);
            Debug.Log("A");
        }

        IEnumerator B()
        {
            yield return new WaitForSeconds(1.0f);
            Debug.Log("B");
        }

        void Start()
        {
            var aStream = Observable.FromCoroutine(_ => A());
            var bStream = Observable.FromCoroutine(_ => B());

            Observable.WhenAll(aStream, bStream)
                      .Subscribe(_ =>
                      {
                          Debug.Log("when all 處理了");
                      });
        }
    }

2.按鈕的並行操作

 public class AllButtonClickedOnceExample : MonoBehaviour
    {
        void Start()
        {
            var leftMouseClickedEvents = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(0)).First();
            var rightMouseClickedEvetns = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(1)).First();

            Observable.WhenAll(leftMouseClickedEvents, rightMouseClickedEvetns)
                      .Subscribe(_ =>
                      {
                          Debug.Log("mouse clicked");
                      });
        }
    }
}

四.事件流的結束OnCompleted 

有的 事件流是有結束事件的,⽐如 Timer、First、Coroutine 等。有的則沒有,⽐如 EveryUpdate 等。

 public class OnCompletedExample : MonoBehaviour
    {
        void Start()
        {
            Observable.FromCoroutine(A)
                      .Subscribe(_ =>
                      {
                          Debug.Log("OnNext:");
                      }, () =>
                      {
                          Debug.Log("OnCompleted:");
                      });
        }

        IEnumerator A()
        {
            yield return new WaitForSeconds(2.0f);
        }
    }

五.Start:讓多執行緒更簡單

多執行緒,是作為⾼級開發者必須具備的⼀種技術。瞭解了多執行緒可以讓我們充分利⽤多核移動端的計算優勢,也可以讓我們的遊戲體驗更平滑。
在 Unity 中我們⼀般⽤ Thread.Start 開啟⼀個執行緒。當邏輯⾮常複雜的時候多執行緒⾮常難以管理。⽽ UniRx 改善了這⼀種狀況。

public class ThreadExample : MonoBehaviour
    {
        void Start()
        {
            var threadAStream = Observable.Start(() =>
            {
                Thread.Sleep(TimeSpan.FromSeconds(1));
                return 10;
            });

            var threadBStream = Observable.Start(() =>
            {
                Thread.Sleep(TimeSpan.FromSeconds(3));
                return 10;
            });

            Observable.WhenAll(threadAStream, threadBStream)
                      .ObserveOnMainThread()
                      .Subscribe(results =>
                      {
                          Debug.LogFormat("{0}:{1}", results[0], results[1]);
                      });
        }
    }

Observable.Start:開啟⼀個執行緒流。

ObserveOnMainThread : 把 WhellAll 結果轉到主執行緒上。這樣 Subscribe ⾥的回撥就可以使⽤Unity 的 API 了(Unity 的很多 API 不可以在其他執行緒中使⽤ )。