🏆 个人愚见,没事写写笔记
🏆《博客内容》: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;
}
}
🔎☀️🍀💥⚙️ ⚠️📧 📝 🛠️📌🌈🔥💡👍🖥️💬📚