Addressable异步加载资源写起来有些地方不太好控制代码结构。所以我简单做了一个AsyncTask,这样代码写起来简单易懂。
[AsyncMethodBuilder(typeof(AsyncSTaskMethodBuilder))]//指定Builder类,async修饰所必须
public class AsyncTask<T> where T : UnityEngine.Object
{
public enum AwaiterStatus
{
Pending = 0,
Succeeded = 1,
Faulted = 2,
Canceled = 3
}
private AwaiterStatus status { get; set; }
private Awaiter<T> awaiter;
T Resualt;
public Awaiter<T> GetAwaiter()
{
status = AwaiterStatus.Pending;
awaiter = new Awaiter<T>(this);
return awaiter;
}
public bool IsComplete()
{
Debug.Log($"AsyncTask -> IsCompleted????{status} {status != AwaiterStatus.Pending}");
return status != AwaiterStatus.Pending;
}
public void OnComplete(T value)
{
Debug.Log($"AsyncTask -> OnComplete");
status = AwaiterStatus.Succeeded;
Resualt = value;
awaiter.TryInvokeContinuation();
}
public T GetResualt()
{
return Resualt;
}
}
public class Awaiter<T> : ICriticalNotifyCompletion where T : UnityEngine.Object
{
Action continuation;
private AsyncTask<T> asyncTask;
internal Awaiter(AsyncTask<T> asyncTask)
{
this.asyncTask = asyncTask;
}
public bool IsCompleted { get { return this.asyncTask.IsComplete(); } }
public void OnCompleted(Action continuation)
{
Debug.Log($"Awaiter -> OnCompleted");
if (IsCompleted)
{
continuation?.Invoke();
}
}
public void UnsafeOnCompleted(Action continuation)
{
this.continuation = continuation;
Debug.Log($"Awaiter -> UnsafeOnCompleted");
if(IsCompleted)
{
continuation?.Invoke();
}
}
public void GetResult()
{
Debug.Log($"Awaiter -> GetResult");
}
public void TryInvokeContinuation()
{
this.continuation?.Invoke();
this.continuation = null;
}
}
使用方式
public AsyncTask<T> LoadAssetInstance<T>(string asstesName, bool isRelease = false, Action<T> callBack = null) where T : UnityEngine.Object
{
AsyncTask<T> task = new AsyncTask<T>();
AsyncOperationHandle handle = Addressables.LoadAssetAsync<T>(asstesName);
handle.Completed += op => {
if (op.Status != AsyncOperationStatus.Succeeded)
{
Debug.LogError($"LoadAsset 加载资源出错{asstesName}");
return ;
}
if (op.Result == null)
{
Debug.LogError($"LoadAsset 没有加载到资源{asstesName}");
return;
}
//Debug.LogFormat("LoadAssetTest Completed!");
var go = GameObject.Instantiate(op.Result as T);
task.OnComplete(go);
callBack?.Invoke(go);
if (isRelease)
{
Addressables.Release(op);
}
};
return task;
}
Debug.Log("测试异步");
var go = AddressableManager.Instance.LoadAssetInstance<GameObject>("JadePanel_Main");
await go;
Debug.Log(go.GetResualt().name);