随风逐叶 随风逐叶
首页
  • Quick Reference (opens new window)
  • EgretEngine开发者文档 (opens new window)
  • TinaX框架
  • SSH教程
  • VSCode插件开发
关于
  • 分类
  • 标签
  • 归档

rontian

从事游戏开发10多年的老菜鸟一枚!
首页
  • Quick Reference (opens new window)
  • EgretEngine开发者文档 (opens new window)
  • TinaX框架
  • SSH教程
  • VSCode插件开发
关于
  • 分类
  • 标签
  • 归档
  • 框架简介
  • TinaX.Core
  • 基于TinaX创建一个扩展库
  • TinaX.VFS
  • TinaX.UIKit
  • TinaX.I18N
  • TinaX.Lua
  • XLua

  • Google.Protobuf
  • Lua-Protobuf
  • 一些优秀的第三方库

    • CatLib

    • UniRx

    • UniTask

      • UniTask
    目录

    UniTask

    # UniTask

    # 什么是UniTask

    UniTask是基于C# 5的async和await异步定制的一套Unity优化的异步解决方案;需要Unity2017以上的版本,并且需要升级c#库, 但并不如UniRx项目提供的更为轻量级,可是UniTask拥有强大的async/await和unity进行交互。

    # 一般什么情况下使用UniTask

    一般来说首先想到的是网络相关的处理和资源加载需要用UniTask来处理,使用UniRx来处理感觉不够用;还有复杂的运算也可以使用UniTask,当作一个线程来使用就好。

    # 基于Unity AsyncOperation拓展的async&awaitAPI

    所有Unity中的异步AsyncOperation都可以使用await来等待异步结果,包括AsyncLoadScene、AsyncLoadAsset、AsyncOperation

    public class No22_UniTask : MonoBehaviour
    {
        async void StartAsync()
        {
            // 加载资源
            var load = await Resources.LoadAsync<TextAsset>("1");
            // 加载场景
            await SceneManager.LoadSceneAsync("SampleScene")
            .ConfigureAwait(Progress.Create<float>(p => Debug.LogFormat("p:{0}", p)));
            // 网络请求
            UnityWebRequest req = UnityWebRequest.Get("http://www.baidu.com");
            var op = await req.SendWebRequest();
        }
        
        void Start()
        {
            StartAsync();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    # UniTask API

    UniTask.WaitUntil
    UniTask.WaitWhile
    UniTask.WaitUntilValueChanged
    UniTask.SwitchToThreadPool
    UniTask.SwitchToTaskPool
    UniTask.SwitchToMainThread
    UniTask.SwitchToSynchronizationContext
    UniTask.Yield
    UniTask.Run
    UniTask.Lazy
    UniTask.Void
    UniTask.ConfigureAwait
    UniTask.DelayFrame
    UniTask.Delay(…, bool ignoreTimeScale = false, …) parameter
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # UniTask.WaitUntil

    一直等待直到达到某种条件,才执行下面的代码

    public class No22_UniTask : MonoBehaviour
    {
        private bool mValue;
    
        async void StartAsync()
        {
            Debug.LogFormat("frame start:{0}", Time.frameCount);
            Observable.TimerFrame(100).Subscribe(_ => mValue = true);
        
            // 一直等待直到达到某种条件,才执行下面的代码
            await UniTask.WaitUntil(() => mValue == true);
            Debug.LogFormat("frame end:{0}", Time.frameCount);
        }
        
        void Start()
        {
            StartAsync();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    # UniTask.WaitWhile

    当达到某种条件才进行等待,条件失败通过

    public class No22_UniTask : MonoBehaviour
    {
        private bool mValue;
    
        async void StartAsync()
        {
            Debug.LogFormat("frame start:{0}", Time.frameCount);
            Observable.TimerFrame(100).Subscribe(_ => mValue = true);
        
            // 当达到某种条件才进行等待,条件失败通过
            await UniTask.WaitWhile(() => mValue == false);
            Debug.LogFormat("frame end:{0}", Time.frameCount);
        }
        
        void Start()
        {
            StartAsync();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    # UniTask.WaitUntilValueChanged

    一直等待直到值有变化了之后才之执行后面的代码

    # UniTask.SwitchToThreadPool

    之后的代码运行在线程池中

    public class No22_UniTask : MonoBehaviour
    {
        private bool mValue;
    
        async void StartAsync()
        {
            Debug.LogFormat("frame start:{0}", Time.frameCount);
            Observable.TimerFrame(100).Subscribe(_ => mValue = true);
        
            //之后的代码运行中线程池中
            await UniTask.SwitchToThreadPool();
            // 当达到某种条件才进行等待,条件失败通过
            await UniTask.WaitWhile(() => mValue == false);
            Debug.LogFormat("frame end:{0}", Time.frameCount);
        }
        
        void Start()
        {
            StartAsync();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    # UniTask.SwitchToTaskPool

    之后的代码运行在任务池中

    # UniTask.SwitchToMainThread

    *之后的代码运行在主线程中

    # UniTask.SwitchToSynchronizationContext

    之后的代码运行在同步句柄中

    # UniTask.Yield

    相当于yiled return [operation]

    public class No22_UniTask : MonoBehaviour
    {
        async void StartAsync()
        {
            Debug.LogFormat("frame start:{0}", Time.frameCount);
            // PlayerLoopTiming.PostLateUpdate  =  WaitForEndOfFrame
            // yield return null
            // yield return WaitForFixedUpdate
            await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
            Debug.LogFormat("frame end:{0}", Time.frameCount);
        }
        
        void Start()
        {
            StartAsync();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    # UniTask.Run

    启动一个标准的线程

    public class No22_UniTask : MonoBehaviour
    {
        async void StartAsync()
        {
            Debug.LogFormat("frame start:{0}", Time.frameCount);
            // 启动一个标准的线程
            await UniTask.Run(() => Debug.Log("heavy task heavy cal"));
            Debug.LogFormat("frame end:{0}", Time.frameCount);
        }
        
        void Start()
        {
            StartAsync();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    # UniTask.Lazy

    启动一个回调线程

    public class No22_UniTask : MonoBehaviour
    {
        private UniTask<int> mLazy;
        async void StartAsync()
        {
            Debug.LogFormat("frame start:{0}", Time.frameCount);
            // 启动一个回调线程
            await UniTask.Lazy<int>(() => UniTask.DelayFrame(100));
            Debug.LogFormat("frame end:{0}", Time.frameCount);
        }
        
        void Start()
        {
            StartAsync();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    # UniTask.Void

    void回调辅助方法

    public class No22_UniTask : MonoBehaviour
    {
        async void StartAsync()
        {
            Debug.LogFormat("frame start:{0}", Time.frameCount);
            // void回调辅助方法
            UniTask.Void(Method);
            Debug.LogFormat("frame end:{0}", Time.frameCount);
        }
    
        private UniTask Method()
        {
            return UniTask.DelayFrame(100);
        }
        
        void Start()
        {
            StartAsync();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    # UniTask.ConfigureAwait

    基于AsyncOperation的拓展配置

    public class No22_UniTask : MonoBehaviour
    {
        async void StartAsync()
        {
            Debug.LogFormat("frame start:{0}", Time.frameCount);
            // 基于AsyncOperation的拓展配置
            Resources.LoadAsync<TextAsset>("1").ConfigureAwait(Progress.Create<float>(p => Debug.LogFormat("p:{0}", p)));
            Debug.LogFormat("frame end:{0}", Time.frameCount);
        }
    
        private UniTask Method()
        {
            return UniTask.DelayFrame(100);
        }
        
        void Start()
        {
            StartAsync();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    # UniTask.DelayFrame

    延时指定的帧数执行下面的代码

    # UniTask.Delay(…, bool ignoreTimeScale = false, …) parameter

    延时指定的时间执行下面的代码

    # UniTaskTracker 可视化任务

    使用UniTask的监视器,可以监视当前执行的哪些任务

    # 其他设置

    Enable AutoReload:是否允许自动加载task
    Enable Tracking: 是否允许跟踪task
    Enable StackTrace:是否允许堆栈跟踪
    Reload:重新加载task列表
    GC.Collect:进行GC回收
    
    1
    2
    3
    4
    5
    上次更新: 2023/10/17, 14:09:52 访问次数: 0
    UniRx入门系列五

    ← UniRx入门系列五

    最近更新
    01
    一些Shell常用的功能写法整理
    10-20
    02
    删除git仓库submodule的步骤
    10-20
    03
    django基本命令
    10-16
    更多文章>
    Copyright © 2017-2025 随风逐叶
    沪ICP备18008791号-1 | 沪公网安备31011502401077号

    网站访问总次数: 0次
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式