版本:unity 5.6 语言:C#
UniRx版本:5.5
总起:
ReactiveX并不是个新技术,百度上一搜就有很多中文的资料,但唯独没有针对Unity的UniRx资料,我这边就开个坑进行介绍。
UniRx的GitHub地址如下:https://github.com/neuecc/UniRx。我这边在csdn上传一份Unity商店中的包:http://download.csdn.net/detail/u012632851/9908069。
Rx由微软公司进行开发,并于2012年开源,现在支持的语言平台有20多种。所以什么是ReactiveX呢?
根据我个人的理解:ReactiveX主要处理时间上异步的各种操作,使用简洁的编码实现需要各种计时器才能完成的功能。
让我们来结合一个简单的例子来说一下。
一个例子:
实现的功能是程序能判断当前的点击是单击还是双击?
在拿到Unity的第一天开始,我就想着Unity本身也没有提供双击,如果想要做一个类似Window双击运行文件的效果该怎么做呢?后来有过一些思路,不过项目上不需要用到,所以没实际写下来。
这次我们来看看我的实现:
// 当前统计到的点击数量
int clickCount = 0;
float dTime = 0;
float maxDTime = 0.25f;
// Update中的实现,所以需要用到dTime来记录时间
void Update ()
{
if (clickCount > 0)
{
// 记录到第一次点击后,开始记录时间
dTime += Time.deltaTime;
// 时间超过了最大时间,打印结果,并重置
if(dTime > maxDTime)
{
if (clickCount == 1)
Debug.Log("单击");
else
Debug.Log("双击");
clickCount = 0;
}
else
{
// 没有超过时间的情况下,又发生了一次点击,增加计数器
if (Input.GetMouseButtonDown(0))
{
dTime = 0f;
++clickCount;
}
}
}
else
{
// 监听第一次点击
dTime = 0f;
if(Input.GetMouseButtonDown(0))
clickCount = 1;
}
}
其实实现过程并不复杂。我自己写了非常多和以上实现类似的程序,心情好用个协程,但是协程也有不方便的地方:无法处理异常、没有返回值。
回到双击功能的实现上来,那么Rx会怎么做呢?
请看以下代码:
void Start()
{
// 每一帧运行,点击鼠标左键的时候触发
var clickStream = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(0));
var obser = clickStream.Buffer(clickStream.Throttle(TimeSpan.FromMilliseconds(250))); //不多说,原理我没研究,但效果跟我上面的实现一样
obser.Where(xs => xs.Count >= 2)
.Subscribe(xs => Debug.Log("DoubleClick Detected ! Count:" + xs.Count));
obser.Where(xs => xs.Count == 1)
.Subscribe(_ => Debug.Log("Once Click"));
}
一共6行代码,看看结果:
就像运行一个方法一样,在初始化的时候设定些参数就能完成Update每帧都需要运行的方法。理解上可能有些困难,但他相对我的实现有什么好处呢?
第一,非常重要,可以非常方便的封装,写个工具类放Rx的代码放进去,需要的一调用就行。不然每次都要去Update中复制粘贴代码,而且还要考虑到其他在Update中运行的代码;
第二,使用Dispose()方法可以随时取消监听,不然你还要设置个flag,在Update中每帧判断flag是否已经为false,然后跳过检测的代码;
第三,代码简洁精悍,我在学C++的时候,有一句话我印象深刻:简洁是一种美德。嗯,所以我这边黑一下Java。
以上的三点足以让我对这个框架心驰神往,我每次在Update中码上三、四百行代码时,我就想着就没有更加简洁的实现吗?直到我现在遇到了UniRx。
当然学习难度比较高,需要一定时间的积累才能写出类似上面的代码。
这个例子先介绍到这,我继续研究这个UniRx。
个人:
ECS的下一个例子等到我实际用过该框架后,再来带着实际经验来讲解,有关注的同学需要等一等。然后UniRx又是个大坑(已经开了不知道多少个坑,不过都会填的放心,我会一直做游戏的),响应式编程我也是第一次接触,Linq我都没咋写过,所以理解的障碍又增加了一层。
ECS和UniRx现在都要实际用到,不学做不了功能,只能说是硬着头皮上。说起来IT技术真正用起来的时候都是一些没有接触过的技术,临时学习整理,尽量去克服,扩展知识面的同时,也锻炼自己快速掌握新技术的能力。
最近Unity官方说要本地化在征求大家的意见,我个人反对本地化,因为你看我最近研究的ECS和UniRx都没有中文,Unity本地化了你去学了,那下一个新的技术难道也要等到本地化了再学?恕我不能苟同,IT技术毕竟主导的是美利坚,学好英语、多看英文资料才是王道。
不过看样子Unity的官方文档是会第一个本地化的,我最近也有文章在做翻译工作,主要提高自己的英语阅读水平和了解Unity各方面的细节,即使Unity官方文档出了,我还是会做下去。