UniTask

1. 异步操作转化为 unitask

1.1 异步加载资源

private async void OnClickLoadText()  
{  
    var loadOperation = Resources.LoadAsync<TextAsset>("test");  
    var text = await loadOperation;  
  
    TargetText.text = ((TextAsset) text).text; 
}

此处的 loadOperation 是一个 ResourceRequest ,而 ResourceRequest 其实就是一个异步操作 ( 继承自 AsyncOperation )。接着此处使用 await ,就会将其转换为 Unitaskawaiter 。代码如下:

public static ResourceRequestAwaiter GetAwaiter(this ResourceRequest asyncOperation)  
{  
    Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
    return new ResourceRequestAwaiter(asyncOperation);  
}

最终这个异步操作得到的就是 awaiter 里面返回的结果:

public UnityEngine.Object GetResult()  
{  
    if (continuationAction != null)  
    {  
        asyncOperation.completed -= continuationAction;  
        continuationAction = null;  
        var result = asyncOperation.asset;  
        asyncOperation = null;  
        return result;  
    }  
    else  
    {  
        var result = asyncOperation.asset;  
        asyncOperation = null;  
        return result;  
    }  
}

最终返回的也就是我们这个 ResourceRequestAwaiter 里面的 GetResult ,也就是这个异步操作的 asset, 即 asyncOperation.asset

如果我们想将此处的功能从 MonoBehaviour 里面迁移到 c# 托管的类,此时可以这样:

此处含有 async 修饰符,因此返回的必须是一个 Task 或者 ValueTask ,而 UniTask 本身就是一个 ValueTask值任务

1.2 异步加载场景

此处的代码示例目的是异步加载一个场景,并且获取其加载进度反应到进度条上面。

此处将这个异步操作转换为 UniTask 之后,在其中添加一个回调 Progress.Create<float> ,即可拿到这个场景加载的进度。

1.3 网络请求的异步操作

此处的 await 其实也是在获得一个 UnityWebRequestAsyncOperationAwaiter ,和第一个加载资源的操作也是有异曲同工之妙了。

代码中间部分就是一个很简单的分割图片的算法。

代码最后的循环是将每帧 sprite 依次赋值,构成类似于动画的样子。此处虽然是死循环,但是有 await 因此是非阻塞的完全没问题。

2.Delay & Wait

Last updated