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的优势
- 易于实现MVC架构。
- 易于实现复杂的异步逻辑。
- 对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被销毁时,会调用IDisposable
的Dispose()
方法。
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)