【Unity】UniTask(异步工具)快速上手

2024-07-21 1627阅读

UniTask(异步工具)

官方文档:https://github.com/Cysharp/UniTask/blob/master/README_CN.md

【Unity】UniTask(异步工具)快速上手
(图片来源网络,侵删)

URL:https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask

优点:0GC,可以在任何地方使用

为Unity提供一个高性能,0GC的async/await异步方案。

优点:

  • 基于值类型的UniTask和自定义的 AsyncMethodBuilder 来实现0GC
  • 使所有 Unity 的 AsyncOperations 和 Coroutines 可等待
  • 基于 PlayerLoop 的任务( UniTask.Yield, UniTask.Delay, UniTask.DelayFrame, etc…) 可以替换所有协程操作
  • 对MonoBehaviour 消息事件和 uGUI 事件进行 可等待/异步枚举 拓展
  • 完全在 Unity 的 PlayerLoop 上运行,因此不使用Thread,并且同样能在 WebGL、wasm 等平台上运行。
  • 带有 Channel 和 AsyncReactiveProperty的异步 LINQ,
  • 提供一个 TaskTracker EditorWindow 以追踪所有UniTask分配来预防内存泄漏
  • 与原生 Task/ValueTask/IValueTaskSource 高度兼容的行为
    1. 相关博客:

      • https://blog.csdn.net/farcor_cn/article/details/119494954
      • 使用案例:

        • 等待1s

          写入async UniTaskVoid

          public async UniTaskVoid Awaittime()
              {
                  Debug.Log("开始");
                  await UniTask.Delay(1000);
                  Debug.Log("结束延时");
              }
          
        • 相关静态方法

          • UniTask.Delay

            延时几秒执行,能选择是以什么update时间来计算。

            UniTask.Delay(1000); //延迟1000ms
            UniTask.Delay(TimeSpan.FromSeconds(1));//延迟1s
            UniTask.Delay(1000, delayTiming: PlayerLoopTiming.FixedUpdate);//以FixedUpdate的时间来等待
            
          • UniTask.DelayFrame

            延时几帧执行

            UniTask.DelayFrame(3);//等待3帧(默认 update循环)
            UniTask.DelayFrame(3, PlayerLoopTiming.FixedUpdate);//等待3帧(Fixedupdate循环)
            
          • UniTask.Yield()

            等待1帧执行,调用即回到主线程执行操作

            await UniTask.Yield();//等待update()下的一帧
            await UniTask.Yield(PlayerLoopTiming.FixedUpdate);//等待下一次fixedUpdate
            
          • **UniTask.SwitchToThreadPool **

          • UniTask.SwitchToMainThread

            用来切换代码是在主线程跑还是线程池里跑

            await UniTask.Yield();
            //之后都在主线程跑
            await UniTask.SwitchToThreadPool();
            //之后都在线程池跑
            await UniTask.SwitchToMainThread();
            //之后回到主线程跑
            

            yield和SwitchToMainThread区别在于,如果已经是主线程下的话,SwitchToMainThread不会再等待一帧,而yield无论是不是在主线程,都会等待1帧。

          • UniTask.WaitUntil

          • UniTask.WaitWhile

            条件等待

            private async UniTaskVoid WaitUntils()
                {
                    Debug.Log("开始");
                    // 等待条件为 true则继续执行,否则等待
                    await UniTask.WaitUntil(() => isActiveAndEnabled);
                    // 在这里可以执行其他逻辑或代码,当 isActiveAndEnabled 为 true 时才会继续执行
                    
                    // 等待条件为 false则继续执行,否则等待
                    await UniTask.WaitWhile(() => isActiveAndEnabled);
                    // 在这里可以执行其他逻辑或代码,当 transform.position.y 不再大于 0 时才会继续执行
                    
                }
            
          • UniTask.WaitUntilValueChanged

            指定对象变化时执行

            var str = await UniTask.WaitUntilValueChanged(this.transform,x =>x.position);//第一个参数时判断目标,第二个参数是判断方法的委托。如果这个返回值变的话,即为发生变化。
            Debug.Log(str);
            
          • UniTask.WhenAll(List)

            同Task.WhenAll()等待所有Task完成后完成,但UniTask版可以返回不同类型的值。

                private async UniTaskVoid StartAll()
                {
                    // 创建异步任务列表
                    List tasks = new List();
                    // 向任务列表添加异步操作
                    tasks.Add(DoTask1Async());
                    tasks.Add(DoTask2Async());
                    tasks.Add(DoTask3Async());
                    // 等待所有任务完成
                    await UniTask.WhenAll(tasks);
                    // 所有任务完成后,执行下面的代码
                    Debug.Log("所有任务已完成");
                }
                private async UniTask DoTask1Async()
                {
                    // 异步操作1的代码
                    await UniTask.Delay(1000);
                    Debug.Log("任务1完成");
                }
                private async UniTask DoTask2Async()
                {
                    // 异步操作2的代码
                    await UniTask.Delay(2000);
                    Debug.Log("任务2完成");
                }
                private async UniTask DoTask3Async()
                {
                    // 异步操作3的代码
                    await UniTask.Delay(3000);
                    Debug.Log("任务3完成");
                }
            
          • UniTask.WhenAny(List)

            同Task.WhenAny()等待其中一个Task完成即为完成。

          • UniTask.Create(Function(UniTask))

            用异步委托快速生成返回UniTask的异步方法。

            private async UniTaskVoid Create()
                {
                    // 创建自定义的异步操作并返回 UniTask 对象
                    UniTask customTask = UniTask.Create(async () =>
                    {
                        Debug.Log("开始自定义异步操作");
                        await UniTask.Delay(1000);
                        Debug.Log("自定义异步操作完成");
                        return "11";
                    });
                    // 等待自定义异步操作完成并获取结果
                    string result = await customTask;
                    // 输出结果
                    Debug.Log($"自定义异步操作的结果:{result}");
                }
            
          • UniTask.Defer(Function(UniTask))

            用异步委托快速生成返回UniTask的异步方法,但在创建时不执行,但在await时才执行。

            private async UniTaskVoid CreateDefer()
                {
                    // 创建自定义的异步操作并返回 UniTask 对象
                    UniTask customTask = UniTask.Defer(async () =>
                    {
                        Debug.Log("开始自定义异步操作");
                        await UniTask.Delay(1000);
                        Debug.Log("自定义异步操作完成");
                        return "11";
                    });
                    // 等待自定义异步操作完成并获取结果
                    string result = await customTask;
                    // 输出结果
                    Debug.Log($"自定义异步操作的结果:{result}");
                }
            
          • UniTask.Lazy(Function(UniTask))

            用异步委托生成一个AsyncLazy型对象,在创建时不执行,但在await时才执行。与Defer不同的是这个可以重复await。

          • UniTask.Void(Function(UniTask))

            直接启动一个异步委托,不考虑其等待。

            	UniTask.Void(
                        async () => 
                        {
                            Debug.Log("aa");
                            await UniTask.Delay(1000);
                        }
                        );
            
          • UniTask.Action/UnityAction(Function(UniTask))

            就是将异步委托封装成Action或UnityAction。

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]