【Unity】使用UniRx来快速完成Unity中的信号层开发工作。

访问官方

网址:https://github.com/neuecc/UniRx/

UniRx(Unity反应式扩展)是.NET 反应式扩展的重新实现。官方 Rx 实现很棒,但在 Unity 上不起作用,并且存在 iOS IL2CPP 兼容性问题。此库修复了这些问题,并为 Unity 添加了一些特定的实用程序。支持的平台是 PC/Mac/Android/iOS/WebGL/WindowsStore/etc 和库。

通常,Unity 中的网络操作需要使用 WWW 和 Coroutine。也就是说,出于以下(和其他)原因,使用 Coroutine 并不是异步操作的良好做法:

协程不能返回任何值,因为其返回类型必须是 IEnumerator。

协程无法处理异常,因为 yield return 语句不能用 try-catch 构造括起来。

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

Rx 治愈了那种 "异步忧郁症"。Rx 是一个库,用于使用可观察集合和 LINQ 样式的查询运算符编写异步程序和基于事件的程序。

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

Unity 通常是单线程的,但 UniRx 有助于对联接、取消、访问游戏对象等进行多线程处理。

UniRx 使用 uGUI 帮助 UI 编程。所有 UI 事件(clicked、valuechanged 等)都可以转换为 UniRx 事件流。

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

学习的代码

csharp 复制代码
using UniRx;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    // 定义一个int类型的信号
    public static ReactiveProperty<int> id = new ReactiveProperty<int>(9);

    // 定义一个int float 类型的信号
    public static ReactiveProperty<(int id, float value)> hello = new ReactiveProperty<(
        int id,
        float value
    )>((0, 1.0f));

    // 定义一个状态变量,判断状态是否会跟随变化
    public string m_str_state = "hello world";

    // 定义通知类型
    public static ScheduledNotifier<float> s_notifier = new ScheduledNotifier<float>();

    // Start is called before the first frame update
    void Start()
    {
        // 监听信号   重点在后面的addto,这样可以绑定到具体的对象,这样当对象注销的时候这个也会注销掉.
        _ = id.Subscribe(
                (value) =>
                {
                    Debug.Log(value);
                    m_str_state = $"fuck_{id.Value}";
                }
            )
            .AddTo(this);

        // 监听并且有状态的传递 ,   这个状态值是不可变的.
        _ = hello
            .SubscribeWithState(
                m_str_state,
                (value, value1) =>
                {
                    Debug.Log(
                        $"id = {value.id} | value = {value.value} | state = {value1} | m_str_state = {m_str_state}"
                    );
                }
            )
            .AddTo(this);

        // 监听
        _ = hello
            .Subscribe(
                (value) =>
                {
                    Debug.Log($" 值发生改变的时候{value.id}  {value.value}");
                },
                (e) =>
                {
                    Debug.Log($" 发生错误{e.Message}");
                },
                () =>
                {
                    Debug.Log($" 值赋值完毕");
                }
            )
            .AddTo(this);

        Debug.Log(id.Value);
        Debug.Log($"初始化得到的值为{hello.Value.id}  {hello.Value.value}");
    }

    // Update is called once per frame
    private void FixedUpdate()
    {
        // 开始测试
        id.Value = id.Value + 1;
        hello.Value = (id: hello.Value.id - 1, value: hello.Value.value + 0.1f);
    }
}
相关推荐
寂寞的船19 小时前
【Unity知识速递】第13期 Unity 内存泄漏排查实战:从 Memory Profiler 到 Lua 引用泄漏的生产级全链路诊断
unity·junit·c#·游戏引擎·lua
寂寞的船2 天前
【Unity Bug挑战】第12期 Awaitable 二次 await 死锁之谜 —— 为什么同一个异步操作等两次就卡死?
unity·c#·游戏引擎·bug
探求虚无3 天前
用 AI 在 Unity 里做一款 RTS:最难的不是生成代码,而是证明它真的能玩
人工智能·unity·游戏引擎
17岁的勇气4 天前
Unity Shader unity文档学习笔记(二十二):shader变体
笔记·学习·unity
寂寞的船5 天前
【Unity知识速递】第10期 Unity GC 零分配实战:从 UnityEngine.Pool 到手动 GC 控制的全链路优化
jvm·unity·c#·游戏引擎·lucene
Martina_03215 天前
AI生成3D场景的霓虹灯一开就糊成光团?用6步检查Emissive、Bloom与曝光
人工智能·3d·ai·自然语言处理·游戏引擎·材质·贴图
寂寞的船7 天前
【Unity知识速递】第8期 IL2CPP 托管堆内存碎片与原生堆交互机制深度解析
unity·游戏引擎·交互
寂寞的船8 天前
【Unity知识速递】第5期 Unity 6.2 深度解析:AI Assistant 登场,World Space UI 与 Sentis 全面升级
人工智能·ui·unity
寂寞的船8 天前
【Unity知识速递】第4期 MCP for Unity:用 AI 自然语言控制编辑器
人工智能·unity·编辑器
淡海水8 天前
09-04-内存-Unity原生对象生命周期
unity·c#·游戏引擎·gc