Unity3D UniRx ReactiveX响应式编程初探1 双击的检测

版本: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行代码,看看结果:

Unity3D UniRx ReactiveX响应式编程初探1 双击的检测_第1张图片


就像运行一个方法一样,在初始化的时候设定些参数就能完成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官方文档出了,我还是会做下去。


你可能感兴趣的:(UniRx,unity3d,Rx,UniRx,响应式编程,双击)