UniRx - Unity响应式扩展

UniRx - Unity响应式扩展

写在前面

本文是翻译UniRx在GitHub中的README

翻译的目的是为了让自己能够在看原文档的时候,真正理解其意。所以,有些地方使用Google的机器翻译。

UniRx是什么

UniRx(Unity的响应式扩展)是.NET响应式扩展的重新实现。官方的响应式扩展很好,但是在Unity中无法工作,并且对iOS IL2CPP兼容性存在问题。本库修复了这些问题并且添加了一些特殊的Unity工具。支持平台PC / Mac / Android / iOS / WebGL / WindowsStore / etc和库。

为什么Rx?

通常来讲,Unity中的网络操作需要使用WWWCoroutine。出于以下(和其他)原因,对于异步操作,使用Coroutine并不是一种好习惯:

  1. 协程不能返回任何值,因为它的返回类型必须是IEnumerator。
  2. 协程不能处理异常,因为yield return语句不能用try-catch结构包围。

这种缺乏可组合性的操作导致操作紧密耦合,这通常会导致庞大的整体式IEnumerator。

Rx可以解决这种“异步坑”。 Rx是一个库,用于使用可观察的集合和LINQ样式的查询运算符来组成基于异步和基于事件的程序。

游戏循环(每次Update,OnCollisionEnter等),传感器数据(Kinect,Leap Motion,VR Input等)都是事件类型。 Rx将事件表示为反应性序列,这些事件既易于组合,又使用LINQ查询运算符支持基于时间的操作。

Unity通常是单线程的,但是UniRx促进连接,取消,访问GameObjects等的多线程。

UniRx帮助使用uGUI进行UI编程。 所有UI事件(单击,更改值等)都可以转换为UniRx事件流。

Unity从2017年开始通过C#升级支持async / await,UniRx系列产品提供与Unity的更轻便,更强大的async / await集成。 请参见Cysharp / UniTask

介绍

很棒的Rx相关文章:The introduction to Reactive Programming you’ve been missing.

下面的代码实现了双击检测:

1
2
3
4
5
6
var clickStream = Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0));

clickStream.Buffer(clickStream.Throttle(TimeSpan.FromMilliseconds(250)))
.Where(xs => xs.Count >= 2)
.Subscribe(xs => Debug.Log("DoubleClick Detected! Count:" + xs.Count));

这个例子展示了以下特性(仅在5行代码中!):

  • 以游戏循环(Update)作为一个事件流
  • 可组合的事件流
  • 自我合并流
  • 易于处理基于时间的操作

网络操作


未完待续…