UniRx第一季學習(六) ------ ObservableWWW/ReactiveCommand /ReactiveCollection/ ReactiveDictionary/AsyncOper
課程地址 : http://www.sikiedu.com/course/271
涼鞋大大的,可以的話大家多支援一波~
一.ObservableWWW優雅的⽹絡請求操作
以往我們不管使⽤ WWW 還是 UnityWebRequest 都要使⽤ Coroutine 去驅動。但是使⽤協程寫出來的程式碼,需要⼀堆判斷,導致程式碼⾮常混亂。
void Start() { ObservableWWW.Get("http://sikiedu.com") .Subscribe(responseText => { Debug.Log(responseText); }, e => { Debug.LogError(e); }); }
除了 Get 也⽀持了 Post,還有 GetWWW 和 PostWWW 這種的輔助封裝,還有 GetAndGetBytes 和PostAndGetBytes。
ObservableWWW 的 API 都可以傳進去⼀個 ScheduledNotifier<T>() ,⽤來監聽下載進度的。Subscribe 之後傳回來的值則是,當前的進度。
private void Start() { var progressObservable = new ScheduledNotifier<float>(); ObservableWWW.GetAndGetBytes("http://liangxiegame.com/media/QFramework_v0.0.9.unitypackage", progress:progressObservable) .Subscribe(bytes => { }); progressObservable.Subscribe(progress => { Debug.LogFormat("進度為:{0}", progress); }); }
⽽且 ObservableWWW 的 Get 和 Post 請求都可以⾃⼰傳對應的 header 和 WWWForm。
除了常⽤的 Get 和 Post 請求,也對 AssetBundle 的載入也做了簡單的封裝。
提供了諸如 ObservableWWW.LoadFromCacheOrDownload 這樣的 API。如果想深⼊瞭解,可以參考 ObservableWWW.cs
另外多個一起下載:
void Start() { var sikieduStream = ObservableWWW.Get("http://sikiedu.com"); var qframeworkStream = ObservableWWW.Get("http://qframework.io"); Observable.WhenAll(sikieduStream, qframeworkStream) .Subscribe(responseTexts => { Debug.Log(responseTexts[0].Substring(0, 100)); Debug.Log(responseTexts[1].Substring(0, 100)); }); }
二.ReactiveCommand
它提供了兩個 API,CanExecte和Execute
Execute ⽅法是被外部調⽤的。也就是這個 Command 的執⾏。這個很容易理解,只要外部調⽤的Execute 就會執⾏。⽽ CanExecute 則是內部使⽤的,並且對外部提供了只讀訪問。當 CanExecute 為 false 時,在外部調⽤ Execute 則該 Command 不會被執⾏。當 CanExecute 為 true 時,在外部調⽤ Execute 則該 Command 會被執⾏。其他的 Observable決定 CanExecute 為 false 或 true ,新建立的 ReactiveCommand 預設 CanExecute 為 true。
以下實現的是滑鼠左鍵按下輸出字元,擡起取消 :
private void Start()
{
var mouseDownStream = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(0)).Select(_ => true);
var mouseUpStream = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonUp(0)).Select(_ => false);
var isMouseUp = Observable.Merge(mouseUpStream, mouseDownStream);
var reactiveCommand = new ReactiveCommand(isMouseUp, false);
reactiveCommand.Subscribe(_ =>
{
Debug.Log("reactive command executed;");
});
Observable.EveryUpdate().Subscribe(_ =>
{
reactiveCommand.Execute();
});
}
當然 ReactiveCommand 也是可以被訂閱(Subscribe) 的,在訂閱之前呢,也可以使⽤ Where 等操作符進⾏事件操作。
三.ReactiveCollection
類似於 List。
ObserverAdd // 當 新的 Item 新增則會觸發
ObserverRemove // 刪除
ObserverReplace // 替換(Update)
ObserverMove // 移動
ObserverCountChanged // 數量有改變(Add、Remove)
四.ReactiveDictionary
功能與 Dictionary 一樣.
ObserverAdd // 當 新的 Item 新增則會觸發
ObserverRemove // 刪除
ObserverReplace // 替換(Update)
ObserverMove // 移動
ObserverCountChanged // 數量有改變(Add、Remove)
五.AsyncOperation載入場景
我們在非同步載入資源或者非同步載入場景的時候往往會⽤到 AsyncOperation。
UniRx 對 AsyncOperation 做了⽀持。使得載入操作可以很容易地監聽載入進度。
public class AsyncOperationExample : MonoBehaviour
{
void Start()
{
var progressObservable = new ScheduledNotifier<float>();
SceneManager.LoadSceneAsync(0).AsAsyncOperationObservable(progressObservable)
.Subscribe(asyncOperation =>
{
Debug.Log("load done");
Resources.LoadAsync<GameObject>("TestCanvas").AsAsyncOperationObservable()
.Subscribe(resourceRequest =>
{
Instantiate(resourceRequest.asset);
});
});
progressObservable.Subscribe(progress =>
{
Debug.LogFormat("載入了:{0}", progress);
});
}
}