在Unity引擎中,从资源中加载文件有两种形式。同步加载Resources.Load和异步加载Resources.LoadAsync,两者区别其实很明显。同步加载资源就是当主线程进行到这里需要加载资源的时候,一直等待资源的加载完毕再继续程序的运行。而异步加载资源则是在加载资源的时候,不暂停其他程序的运行。相当于重新开辟了一段协程,专门用于资源的加载。 ResourceManager的实现如下。
public class ResManager : ISingleton
{
public static ResManager Instance => Singleton<ResManager>.Instance;
public void Init() { }
/// <summary>
/// 同步加载资源
/// </summary>
/// <typeparam name="T">资源类型</typeparam>
/// <param name="name">资源名</param>
/// <returns></returns>
public T Load<T>(string name) where T:Object {
T res = Resources.Load<T>(name);
if (res is GameObject)
GameObject.Instantiate(res);
else//TextAsset AudiClip
return res;
return res;
}
/// <summary>
/// 外部的异步加载资源的接口
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name">资源名</param>
/// <param name="callback"></param>
public void LoadAsync<T>(string name,UnityAction<T> callback) where T:Object
{
//开启协程
MonoManager.Instance.StartCoroutine(ReallyLoadAsync(name,callback));
}
/// <summary>
///异步加载资源的协程函数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <param name="callback"></param>
/// <returns></returns>
private IEnumerator ReallyLoadAsync<T>(string name,UnityAction<T> callback) where T :Object {
ResourceRequest r = Resources.LoadAsync<T>(name);
yield return r;
if (r.asset is GameObject)
callback(GameObject.Instantiate(r.asset) as T);
else
callback(r.asset as T);
}
}
首先第一步,完成同步加载的方法。
在Load<T>方法内部直接调用Resources.Load<T>接口,并且判定若资源的类型,若为GO类型则直接实例化,若为其他类型如:TextAsset或者AudioClip则返回出去。
第二步实现异步加载
由于异步加载需要开启协程,我们就直接声明一个ReallyLoadAsync<T>的协程函数,函数的参数的参数列表有两个参数string name资源名和UnityAction<T>返回值为泛型的委托,在函数内部执行Resourecs.LoadAsync<T>资源加载,然后将返回的ResourceRequest资源请求返回出去。等待资源加载完毕后,判断资源类型将资源转化为泛型T后作为参数传递到委托中去。
第三步调用ResManager
直接将参数为GameObject的函数护着lambad表达式传入委托中执行即可。代码如下:
public class Test:MonoBehaviour{
void Start(){
ResManager.Intance.LoadResources<GameObject>("Cube",(obj)=>
{obj.transformposition=Vector3.zero;});
}
public void TestFunc(GameObject obj){
//TODO
}
}
以上就是资源加载管理器ResourcesManager的实现。