UniTask

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

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

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

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

🌟 为什么 Unity 需要 UniTask?

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

问题 说明
GC 压力大 Task 内部大量使用堆分配,频繁调用会导致垃圾回收(GC),引发卡顿
不支持协程上下文 无法自然地在主线程(Unity 主线程)中 await,容易出现跨线程访问 GameObject 的异常
缺乏 Unity 特有等待机制 无法直接 await WaitForSecondsNextFrameUntilRender 等 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;
        }
    }

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

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

相关推荐
黄思搏1 天前
基于标注平台数据的 Unity UI 自动化构建工作流设计与工程实践
ui·unity·蓝湖·vectoui
羊羊20351 天前
开发手札:Unity6000与Android交互
android·unity·android-studio
Sator12 天前
Unity AStarPath的踩坑点
unity
星河耀银海2 天前
Unity基础:摄像机Camera的参数设置与视角控制
unity·游戏引擎·lucene
星河耀银海2 天前
Unity基础:Transform组件的位移、旋转与缩放详解
unity·游戏引擎·lucene
海清河晏1113 天前
数据结构 | 单链表
数据结构·unity·dreamweaver
mxwin3 天前
Unity URP 下 MatCap 技术详解 无视光照环境的卡通与质感渲染方案
unity·游戏引擎
山檐雾4 天前
OctreeNode
unity·c#·八叉树
WarPigs4 天前
Unity协程返回值的解决方案
unity·游戏引擎
WarPigs4 天前
Unity单例笔记
unity·游戏引擎