Unity Resources.LoadAsync 优雅的写法

        传统写法中 Resources.LoadAsync("path"),保存回调ResourceRequest 开启一个协程或者定时器,每帧去判断一下 ResourceRequest.isDone是否完成,这样每写一句Resources.LoadAsync就得新增一个定时器,如果使用Resources.Load同步加载很大预制体时会卡顿掉帧,所以我们的程序员宗旨就是能躺着绝不站着。

        经过我的修改,使用起来相当舒服,有以下特点:

1、减少后续繁琐的代码,减少重复代码,使用异步编程方式,一目了然,优雅实在是太优雅了。

2、还没想好。。。。。。。。。。。。。

        缺陷:

 1、如果是需要显示加载进度条的还是老老实实增加一个协程每帧获取进度吧。

首先是新建一个全局文件工具类:(可以直接复制)

using UnityEngine;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using System;


public static class ExtensionsResources
{
    public static ResourceRequestAwaiter GetAwaiter(this ResourceRequest request) => new ResourceRequestAwaiter(request);

    public static async Task<T> LoadResourcesAsync<T>(string path) where T : UnityEngine.Object
    {
        var gres = Resources.LoadAsync(path);
        await gres;
        return gres.asset as T;
    }

}

public class ResourceRequestAwaiter : INotifyCompletion
{
    public Action Continuation;
    public ResourceRequest resourceRequest;
    public bool IsCompleted => resourceRequest.isDone;
    public ResourceRequestAwaiter(ResourceRequest resourceRequest)
    {
        this.resourceRequest = resourceRequest;

        //注册完成时的回调
        this.resourceRequest.completed += Accomplish;
    }

    //awati 后面的代码包装成 continuation ,保存在类中方便完成是调用
    public void OnCompleted(Action continuation) => this.Continuation = continuation;

    public void Accomplish(AsyncOperation asyncOperation) => Continuation?.Invoke();

    public void GetResult() {}
}

使用方法 :

using UnityEngine;


public class Test : MonoBehaviour
{
    //使用 await 等待加载完成, Star这个方法必须是 有async 修饰  
    async void Start()
    {
       
        GameObject go = await ExtensionsResources.LoadResourcesAsync<GameObject>("Cube");
        Debug.Log(go.name);
        Instantiate(go);

    }
}