IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> UniRX_UniTask_学习记录_01_概述 -> 正文阅读

[游戏开发]UniRX_UniTask_学习记录_01_概述

第1章 概述

1.1 UniRx是什么

UniRx是以Reactive Extensions为基础的胃Unity的非同期和事件处理的库。

1.2 UniRx的导入方法

1.21 从 Unity Asset Store 导入

https://assetstore.unity.com/packages/tools/integration/unirx-reactive-extensions-for-unity-17276

1.22 从Github 下载最新的release包 导入

https://github.com/neuecc/UniRx

1.3 UniRx的用途

  • 非同期(异步)处理

  • 事件的处理

1.31 异步(非同期)处理

异步处理是什么

当某个处理(函数)在执行的时候,并不等到这个处理结束而去执行别的处理的这种行为叫做【异步处理】,Unity的Coroutine就是异步处理的一种。

异步处理的缺点
  • 需要对异步处理的结果进行管理

  • 能确实都将异步处理取消/中断的手段

  • 需要对执行Context(处理执行时位置和时机)进行管理

想要安全的进行异步处理,以上的一些管理手段都是必要的,UniRx则是对这些提供了这些管理手段。

异步处理和UniRx

UniRx由Observable,Operator,Scheduler这三个部分组成

| 名字 | 用途 |

| ---------- | ------------------------------------------------------ |

| Observable | 异步处理的结果和对这个处理内容的一系列流程的管理的手段 |

| Operator | Observable对复杂的处理进行辅助的手段 |

| Scheduler | Observable对执行Context进行管理的手段 |

UniRx异步处理的使用例子

    using System;

using System.Collections;

using UniRx;

using UnityEngine;

using UnityEngine.Networking;

using UnityEngine.UI;

namespace Sample.Section1

{

    public class DownloadTexture : MonoBehaviour

    {

        /// <summary>

        /// UGUI 的 RawImage

        /// </summary>

        [SerializeField] private RawImage _rawImage;

        private void Start()

        {

            //想要表示的画像的address

            var url = "https://pbs.twimg.com/media/EVAhiXWUwAQx5oD?format=jpg&name=4096x4096";



            //取得Texture

            //例外发生时 尝试3回

            GetTextureAsync(url)

                .OnErrorRetry(

                    onError: (Exception _) => { },

                    retryCount: 3

                ).Subscribe(result => { _rawImage.texture = result; },

                    error => { Debug.Log(error); })

                .AddTo(this);

        }

        /// <summary>

        /// 启动Coroutine,并把结果用 Observable返回

        /// </summary>

        /// <param name="url"></param>

        /// <returns></returns>

        private IObservable<Texture> GetTextureAsync(string url)

        {

            return Observable.FromCoroutine<Texture>(observer =>

            {

                return GetTextureCoroutine(observer, url);

            });

        }

        /// <summary>

        /// 用Coroutine进行图片下载

        /// </summary>

        /// <param name="observer"></param>

        /// <param name="url"></param>

        /// <returns></returns>

        private IEnumerator GetTextureCoroutine(IObserver<Texture> observer, string url)

        {

            using (var uwr = UnityWebRequestTexture.GetTexture(url))

            {

                yield return uwr.SendWebRequest();

                if (uwr.result == UnityWebRequest.Result.ConnectionError

                    || uwr.result == UnityWebRequest.Result.ProtocolError)

                {

                    //Error发生时 发送 OnError 消息

                    observer.OnError(new Exception(uwr.error));

                    yield break;

                }

                var result = ((DownloadHandlerTexture) uwr.downloadHandler).texture;

                //成功时 发送OnNext/OnCompleted消息

                observer.OnNext(result);

                observer.OnCompleted();

            }

        }

    }

}

GetTextureCoroutine方法,使用Coroutine对从指定的url下载Texture,并通过用UniRx(Observable) 来对不同的结果进行返回。


GetTextureCoroutine(IObserver<Texture> observer, string url)

        {

            using (var uwr = UnityWebRequestTexture.GetTexture(url))

            {

                yield return uwr.SendWebRequest();

                if (uwr.result == UnityWebRequest.Result.ConnectionError

                    || uwr.result == UnityWebRequest.Result.ProtocolError)

                {

                    //Error发生时 发送 OnError 消息

                    observer.OnError(new Exception(uwr.error));

                    yield break;

                }

                var result = ((DownloadHandlerTexture) uwr.downloadHandler).texture;

                //成功时 发送OnNext/OnCompleted消息

                observer.OnNext(result);

                observer.OnCompleted();

            }

        }

    }

}

GetTextureAsync方法,则是把Coroutine变化成Observable


        /// <summary>

        /// 启动Coroutine,并把结果用 Observable返回

        /// </summary>

        /// <param name="url"></param>

        /// <returns></returns>

        private IObservable<Texture> GetTextureAsync(string url)

        {

            return Observable.FromCoroutine<Texture>(observer =>

            {

                return GetTextureCoroutine(observer, url);

            });

        }

然后就是Start方法里,订阅由GetTextureAsync方法生成的Observable,OnErrorRetry 是 Operator中的1种,可以对出错时的处理和再处理进行指定,Subscribe()是Observable的用来接受Observable的函数,结果发行的时候,订阅的函数会被执行


        private void Start()

        {

            //想要表示的画像的address

            var url = "https://pbs.twimg.com/media/EVAhiXWUwAQx5oD?format=jpg&name=4096x4096";



            //取得Texture

            //例外发生时 尝试3回

            GetTextureAsync(url)

                .OnErrorRetry(

                    onError: (Exception _) => { },

                    retryCount: 3

                ).Subscribe(result => { _rawImage.texture = result; },

                    error => { Debug.Log(error); })

                .AddTo(this);

        }

像这样,UniRx把异步处理变成Observable,之后可以通过链式方法进行复杂的处理,和别的一步处理并行,处理结束后进行别的异步处理都可以。

和async/await比较

UniRx可以使用链式进行复杂的处理,但是简单的异步处理反而会显得很冗长,这是他的缺点,

现在 Unity可以使用C#7.3/.NET Standard2.0 的API,可以使用async/await。这个async/await 可以像同步处理一样写异步处理,所以简单的异步处理使用async/await场合更多,而不是UniRx。

UniTask

UniTask是UniRx的姐妹库一样的存在,对Unity的Async/Await进行了强化的库

上面的例子可以和UniTask并用


using System;

using System.Collections;

using System.Threading;

using Cysharp.Threading.Tasks;

using UniRx;

using UnityEngine;

using UnityEngine.Networking;

using UnityEngine.UI;

namespace Sample.Section1.Async

{

    /// <summary>

    /// 下载指定的图片

    /// 设定到rawImage

    /// </summary>

    public class DownloadTextureUniTask : MonoBehaviour

    {

        /// <summary>

        /// UGUI 的 RawImage

        /// </summary>

        [SerializeField] private RawImage _rawImage;

        private void Start()

        {

            //取得 跟这个GameObject绑定的CancellationToken

            var token = this.GetCancellationTokenOnDestroy();



            //设置图片

            SetupTextureAsync(token).Forget();

        }

        private async UniTaskVoid SetupTextureAsync(CancellationToken token)

        {

            try

            {

                //想要表示的画像的address

                var url = "https://pbs.twimg.com/media/EVAhiXWUwAQx5oD?format=jpg&name=4096x4096";

                //想要使用UniRx的Retry,把UniRX变成 IObservable

                var observable = Observable

                    .Defer(() =>

                        //UniRx -> IObservable

                        GetTextureAsync(url, token).ToObservable()).Retry(3);

                //Observable 也可以使用await 

                var texture = await observable;

                _rawImage.texture = texture;

            }

            catch (Exception e)when (!(e is OperationCanceledException))

            {

                Debug.LogError(e);

            }

        }

        //使用async/await 代替 Coroutine

        private async UniTask<Texture> GetTextureAsync(string url, CancellationToken token)

        {

            using (var uwr = UnityWebRequestTexture.GetTexture(url))

            {

                await uwr.SendWebRequest().WithCancellation(token);

                return ((DownloadHandlerTexture) uwr.downloadHandler).texture;

            }

        }       

    }

}

1.32 事件处理的利用

事件处理是当条件满足时发行事件消息,接受消息的一边会执行。

Unity开发会经常使用到各种事件。

事件处理和UniRx

UniRx提供Observable,很擅长对事件进行处理

而且Operator非常强力,复杂的事件处理可以简单的写出来。

UniRx事件处理的使用例


using System;

using UniRx;

using UniRx.Triggers;

using UnityEngine;

namespace Sample.Section1

{

    public class ThrottleButton : MonoBehaviour

    {

        private void Start()

        {

            //Update()每一帧对Fire Btn 有没有被按下进行判定

            //按下了就调用Subscribe对处理

            //然后无视30帧

            this.UpdateAsObservable()

                .Where(_ => Input.GetButtonDown("Fire1"))

                .ThrottleFirstFrame(30)

                .Subscribe(_ =>

                {

                    Debug.Log("Fire");

                });

        }

    }

}

UniRx的UpdataAsObservable() 可以把Undate()转化为Observable的消息。

ThrottleFirstFrame 是当OnNext消息发行后会停止一段时间,

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:17:32  更:2022-01-01 14:19:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 21:02:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码