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;
        }
    }

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

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

相关推荐
June bug8 小时前
【领域知识】休闲游戏一次发版全流程:Google Play + Apple App Store
unity
星夜泊客10 小时前
C# 基础:为什么类可以在静态方法中创建自己的实例?
开发语言·经验分享·笔记·unity·c#·游戏引擎
dzj202111 小时前
PointerEnter、PointerExit、PointerDown、PointerUp——鼠标点击物体,则开始旋转,鼠标离开或者松开物体,则停止旋转
unity·pointerdown·pointerup
心前阳光12 小时前
Unity 模拟父子关系
android·unity·游戏引擎
在路上看风景15 小时前
26. Mipmap
unity
咸鱼永不翻身17 小时前
Unity视频资源压缩详解
unity·游戏引擎·音视频
在路上看风景17 小时前
4.2 OverDraw
unity
在路上看风景18 小时前
1.10 CDN缓存
unity
ellis19701 天前
Unity插件SafeArea Helper适配异形屏详解
unity
nnsix1 天前
Unity Physics.Raycast的 QueryTriggerInteraction枚举作用
unity·游戏引擎