zhouqijie

UniRx概述

Siki:UniRx是Unity的一个响应式编程框架。用于优化异步逻辑的实现。

Siki:Rx只是一套标准,在其他语言也有实现。UniRx是Unity的Rx实现。
Siki:ReactiveExtensions的优势就是处理时间上异步的逻辑,而游戏编程中有很多的异步逻辑。

Siki:UniRx将时间上异步事件转换为响应式的事件序列,通过Linq操作可以很简单地组合起来,还支持时间操作。

Rx

Siki: ReactiveX是ReactiveExtensions的缩写,⼀般简写为Rx,最初是LINQ的⼀个扩展,由微软的架构师ErikMeijer领导的团队开发,在2012年11⽉开源,Rx是⼀个编程模型,⽬标是提供⼀致的编程接⼝,帮助开发者更⽅便的处理异步数据流,Rx 库⽀持 .NET、JavaScript 和 C++,Rx 近⼏年越来越流⾏了,现在已经⽀持⼏乎全部的流⾏编程语⾔了,Rx的⼤部分语⾔库由ReactiveX这个组织负责维护,⽐较流⾏的有RxJava/RxJS/Rx.NET,⽽Unity的版本,就是UnIRx。

Microsoft的定义:Rx是⼀个函数库,让开发者可以利⽤可观察序列和LINQ⻛格查询操作符来编写异步和基于事件的程序,使⽤ Rx,开发者可以⽤Observables 表示异步数据流,⽤LINQ操作符查询异步数据流, ⽤Schedulers参数化异步数据流的并发处理。Rx 可以这样定义:Rx=Observables+LINQ+Schedulers。

ReactiveX.io官⽅的定义:Rx是⼀个使⽤可观察数据流进⾏异步编程的编程接⼝,ReactiveX结合了观察者模式、迭代器模式和函数式编程的精华。

使用UniRx的优势

  1. 易于实现MVC架构。
  2. 易于实现复杂的异步逻辑。
  3. 对UGUI的增强和扩展。

Siki:UniRx的出现解决了回调、消息、协程的问题。它介于回调和事件之间。
Siki:UniRx也有事件的概念,但是UniRx中的事件像流水一样,我们只需要简单地进行组织、变换、过滤、合并。
Cre:即不需要手动定义和触发一个事件。





UniRx基本语句和用法

定时功能实现

Observable.Timer(System.TimeSpan.FromSeconds(1))
            .Subscribe(_ => { Debug.Log("DoSomething"); });

独立的Update

Siki:MonoBehaviour中Update有时会掺杂一些互相无关的逻辑,使得代码不易阅读。可以用UniRx监听Update事件。

一个用UniRx监听Update中鼠标点击事件的例子:

Observable.EveryUpdate()                        //开启Update的事件监听
    .Where(_ => Input.GetMouseButtonDown(0))    //过滤(条件判断)
    .First()                                    //只获取第一次的点击事件
    .Subscribe(_ => {  Debug.Log("click");  }); //订阅事件

Siki:如果用传统方式实现,需要在Update方法里面编写代码,并且还需要一个成员变量来记录点击次数。

AddTo操作符

Siki:AddTo可以用来进行与UniRx进行销毁事件的绑定,也就是GameObject或者MonoBehavior被销毁时,同样去销毁正在进行的UniRx任务。

Observable.Timer(System.TimeSpan.FromSeconds(1))
    .Subscribe(_ => { Debug.Log("DoSomething"); })
    .AddTo(this);//or gameobj

Siki:AddTo本质上是一个静态扩展关键字,它对IDisposable进行了扩展。任何实现了IDisposable的接口都可以使用AddTo API,不管是不是UniRx的API。当GameObject被销毁时,会调用IDisposableDispose()方法。
Siki:AddTo使UniRx的使用更加安全,在开启Observable.EveryUpdate时调用当前脚本的方法,则不会造成引用异常等错误。

public class DisposableTest : System.IDisposable
{
    public void Dispose()
    {
        Debug.Log("Dispose Test");
    }
}
public class Test : MonoBehaviour
{
    private DisposableTest tester = new DisposableTest();
    public void Start()
    {
        tester.AddTo(this);
    }
    private void OnDestroy()
    {
        Debug.Log("DestroyMono");
    }
}

Where操作符

Where可以理解为条件语句,可以用来过滤不满足条件的事件。

First操作符

获取第一个通过的事件。

First还可以传入一个条件,代替Where的作用。

(END)