UniRx基本了解

一. Unity 响应式编程:UniRx

1. 前言

先前开发游戏过程中,有用到Zenject + UniTask + UniRx + Localization + GoogleSheet + Addressable的方式来开发游戏,后续会逐个介绍,本篇进行UniRx的介绍,希望起到抛砖引玉作用。
在Unity开发中,响应式编程(Reactive Programming)是一种非常强大的编程范式,它可以帮助我们更好地处理异步事件流。UniRx 是一个专为Unity设计的响应式编程库,它基于Reactive Extensions (Rx) 实现,提供了丰富的功能和灵活的API。本文将详细介绍UniRx的使用方法和注意事项。

2.UniRx 的好处和坏处

1.好处

  • 简洁的事件处理:UniRx 提供了简洁的API,可以轻松处理复杂的事件流。
  • 强大的组合操作:UniRx 提供了丰富的操作符,可以对事件流进行过滤、转换、组合等操作。
  • 与Unity无缝集成:UniRx 支持Unity的各种事件,如Update、FixedUpdate、OnDestroy等。
  • 提高代码可读性:响应式编程可以使代码更加简洁和易读,减少回调地狱和状态管理的复杂性。

2.坏处

  • 学习曲线陡峭:响应式编程的概念和API较为复杂,需要一定的学习成本。
  • 性能开销:在高频率事件处理和大量数据流操作时,可能会带来一定的性能开销。
  • 调试困难:由于事件流的异步和组合特性,调试和定位问题可能会比较困难。

3.UniRx 与 LINQ 的区别

  • LINQ:主要用于对集合(如数组、列表等)进行查询和操作,操作的是静态数据。
  • UniRx:主要用于处理异步事件流,操作的是动态数据。
// LINQ 示例
int numbers = { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
Debug.Log("Even numbers: " + string.Join(", ", evenNumbers));

// UniRx 示例
Observable.Range(1, 5)
    .Where(n => n % 2 == 0)
    .Subscribe(n => Debug.Log("Even number: " + n));

在上面的示例中,LINQ 用于对数组进行查询,而 UniRx 用于处理动态的事件流。

4.UniRx 的基本用法

1.创建Observable

UniRx 提供了多种方式来创建Observable对象。

 // 创建一个简单的Observable
 var observable = Observable.Return(42);
   observable.Subscribe(value => Debug.Log("Received value: " + value));

   // 创建一个定时Observable
   var timer = Observable.Timer(System.TimeSpan.FromSeconds(1));
   timer.Subscribe(_ => Debug.Log("Timer triggered"));

   // 创建一个范围Observable
   var range = Observable.Range(1, 5);
   range.Subscribe(value => Debug.Log("Range value: " + value));

2.操作符

UniRx 提供了丰富的操作符来对Observable进行操作。

Observable.Range(1, 10)
            .Where(n => n % 2 == 0)
            .Select(n => n * n)
            .Subscribe(n => Debug.Log("Processed value: " + n));

在上面的示例中,我们使用 Where 操作符过滤偶数,并使用 Select 操作符对值进行平方处理。

3.订阅

订阅是响应式编程的核心,通过订阅来处理Observable的事件。

Observable.EveryUpdate()
            .Subscribe(_ => Debug.Log("Update event"))
            .AddTo(this); // 自动取消订阅

上面的示例中,我们订阅了 EveryUpdate 事件,并在 MonoBehaviour 销毁时自动取消订阅。

4.网络操作

UniRx 可以与Unity的网络操作结合使用,处理异步的网络请求。

 private void Start()
    {
        FetchData("https://jsonplaceholder.typicode.com/todos/1")
            .Subscribe(response => Debug.Log("Response: " + response));
    }

    private IObservable<string> FetchData(string url)
    {
        return Observable.FromCoroutine<string>(observer => FetchDataCoroutine(url, observer));
    }

    private IEnumerator FetchDataCoroutine(string url, IObserver<string> observer)
    {
        using (UnityWebRequest request = UnityWebRequest.Get(url))
        {
            yield return request.SendWebRequest();

            if (request.result == UnityWebRequest.Result.Success)
            {
                observer.OnNext(request.downloadHandler.text);
                observer.OnCompleted();
            }
            else
            {
                observer.OnError(new System.Exception(request.error));
            }
        }
    }

我们使用 Observable.FromCoroutine 方法将 UnityWebRequest 的协程转换为Observable对象。

5.并行操作

UniRx 提供了多种方式来处理并行操作,可以使用 Merge、Zip 等操作符。

var observable1 = Observable.Timer(System.TimeSpan.FromSeconds(1)).Select(_ => "Task 1 completed");
        var observable2 = Observable.Timer(System.TimeSpan.FromSeconds(2)).Select(_ => "Task 2 completed");

        Observable.Merge(observable1, observable2)
            .Subscribe(message => Debug.Log(message));

我们使用 Merge 操作符将两个Observable合并,并行执行它们。

6.UI 操作

UniRx 可以与Unity的UI系统结合使用,处理UI事件。

1.按钮点击事件
myButton.OnClickAsObservable()
            .Subscribe(_ => myText.text = "Button clicked!");
2.动条事件
mySlider.OnValueChangedAsObservable()
            .Subscribe(value => myText.text = "Slider value: " + value);
3.Toggle 切换事件
 myToggle.OnValueChangedAsObservable()
            .Subscribe(isOn => myText.text = "Toggle is " + (isOn ? "On" : "Off"));
4.输入框事件
 myInputField.OnValueChangedAsObservable()
            .Subscribe(text => myText.text = "Input: " + text);

5.注意事项

  • 内存泄漏:在使用UniRx时,需要注意订阅的取消,以避免内存泄漏。可以使用 AddTo 方法将订阅与 MonoBehaviour 的生命周期绑定。
  • 性能开销:在高频率事件处理和大量数据流操作时,可能会带来一定的性能开销,需要注意优化。
  • 调试困难:由于事件流的异步和组合特性,调试和定位问题可能会比较困难。可以使用 Do 操作符来调试事件流。
Observable.Range(1, 5)
            .Do(value => Debug.Log("Before filter: " + value))
            .Where(value => value % 2 == 0)
            .Do(value => Debug.Log("After filter: " + value))
            .Subscribe(value => Debug.Log("Final value: " + value));

6.总结

UniRx 是一个非常强大的响应式编程库,可以帮助我们更高效地处理异步事件流,提高代码的可读性和可维护性。希望大家在实际项目中能够灵活应用UniRx,提高代码质量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值