UniTask

🏆 个人愚见,没事写写笔记

🏆《博客内容》:Unity3D开发内容

🏆🎉欢迎 👍点赞✍评论⭐收藏

UniTask 是一个为 Unity 引擎量身打造的高性能、零分配(allocation-free)异步编程库,用于替代或增强 C# 原生的 Task 和 async/await 在 Unity 环境中的使用。

🌟 为什么 Unity 需要 UniTask?

在 Unity 中直接使用 C# 的 async/await + Task 会遇到以下问题:

问题 说明
GC 压力大 Task 内部大量使用堆分配,频繁调用会导致垃圾回收(GC),引发卡顿
不支持协程上下文 无法自然地在主线程(Unity 主线程)中 await,容易出现跨线程访问 GameObject 的异常
缺乏 Unity 特有等待机制 无法直接 await WaitForSeconds、NextFrame、UntilRender 等 Unity 协程原语
异常处理不友好 Task 的异常若未观察(observed),会静默失败或延迟抛出

UniTask 正是为解决这些问题而生

🌟 怎么使用UniTask?

⚙️在使用 UniTask 时

等待:使用 await 可以 UniTask 的方法,

不等待:_=方法()或者方法.Forget()

1.等待 N 帧

1.1 等待下一帧

cs 复制代码
await UniTask.NextFrame();

1.2 等待固定更新

cs 复制代码
await UniTask.WaitForFixedUpdate();

1.3 等待时间(毫秒)

cs 复制代码
await UniTask.Delay(1000);

1.4 等待时间(秒)

cs 复制代码
await UniTask.Delay(TimeSpan.FromSeconds(1));

1.5 等待条件成立/等待条件不成立

cs 复制代码
    private int count = 0;
    private async UniTask Start()
    {
        Debug.Log("Start");
        await UniTask.WaitUntil(() => count > 0);//只有当上述条件满足后才会打印
        await UniTask.WaitWhile(() => count == 0);//只有当上述条件不满足后才会打印
        Debug.Log("Start End");
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            count++;
        }
    }

2.替代协程

cs 复制代码
 private async UniTask Start()
    {
        Debug.Log("Start");
        // _ = TestAsync(); //不等待,只是触发执行这个方法
        // TestAsync().Forget(); //不等待,只是触发执行这个方法,但是有UniTask的错误检测
        await TestAsync(); //等待
        Debug.Log("Start End");
    }

    private async UniTask TestAsync()
    {
        Debug.Log("TestAsync Start");
        await UniTask.Delay(TimeSpan.FromSeconds(2f));
        Debug.Log("TestAsync End");
    }

3.生命周期管理(防内存泄漏):当该物体销毁会终止方法

cs 复制代码
 private CancellationToken _Ct;
    private async UniTask Start()
    {
        _Ct = this.GetCancellationTokenOnDestroy();
        Debug.Log("Start");
        await TestAsync(_Ct); //等待
        Debug.Log("Start End");
    }

    private async UniTask TestAsync(CancellationToken CancellationToken)
    {

        Debug.Log("TestAsync Start");
        await UniTask.Delay(TimeSpan.FromSeconds(3f), cancellationToken: CancellationToken);
        Debug.Log("TestAsync End");
    }

4.进度

4.1 实现接口

cs 复制代码
public struct DebugProgress : IProgress<float>
{
    public void Report(float value)
    {
        Debug.Log($"Progress: {value * 100}%");
    }
}

4.2 将进度添加到.ToUniTask 的参数中

cs 复制代码
  public static async UniTask<string> HTTPGetAsync(string url, CancellationToken ct)
    {
        using var uwr = UnityWebRequest.Get(url);

        DebugProgress debugProgress = new DebugProgress();
        await uwr.SendWebRequest().ToUniTask(cancellationToken: ct, progress: debugProgress);

        if (uwr.result != UnityWebRequest.Result.Success)
        {
            var errorMsg = $"HTTP request failed: {uwr.error} (Status: {uwr.responseCode})";
            Debug.LogError(errorMsg);
            throw new System.Exception(errorMsg);
        }
        else
        {
            var response = uwr.downloadHandler.text;
            Debug.Log($"Response: {response}");
            return response;
        }
    }

🔎☀️🍀💥⚙️ ⚠️📧 📝 🛠️📌🌈🔥💡👍🖥️💬📚

🚀感谢:🎉欢迎 👍点赞✍评论⭐收藏

相关推荐
Martina_03213 天前
AI生成3D场景导入 Unity/Unreal 后,NPC 总串层?用6步检查导航高度与跨层连接
人工智能·游戏·数学建模·3d·unity·自然语言处理·aigc
小贺儿开发3 天前
Unity 局域网遥控幻灯片展示工具 3.0
科技·http·unity·工具·ppt·通信·网页
WarPigs5 天前
Unity对象不应该使用null传播的问题
unity
每日出拳老爷子6 天前
【VR】【Unity】抓走转放系列21|一天搭完门和抽屉工具槽:小场景按这个次序拼装
unity·vr·驱动·排错·snap zone
淡海水7 天前
02-02-原理篇-分代GC
算法·unity·c#·游戏引擎·.net·gc
小贺儿开发7 天前
Unity 文物新生 会讲故事的文物展墙
人工智能·科技·unity·ai·视频·互动·演示
淡海水7 天前
02-03-原理篇-大对象堆
unity·c#·游戏引擎·.net·gc
WarPigs8 天前
Unity在Create菜单添加创建自定义脚本模板选项
unity
淡海水8 天前
02-01-原理篇-Mark-Sweep与变种算法
算法·unity·c#·游戏引擎·.net·gc
babywang08 天前
Unity笔记--塔防游戏中的ECS架构:从原理到实战的全面解析
unity·ecs架构