1、根据资源名或标签名加载多个对象
加载多个资源
//加载资源
//参数一:资源名或标签名
//参数二:加载结束后的回调函数
//参数三:如果为true表示当资源加载失败时,会自动将已加载的资源和依赖都释放掉;如果为false,需要自己手动来管理释放
AsyncOperationHandle<IList<Object>> handle = Addressables.LoadAssetsAsync<Object>("Red", (obj) =>
{
//print(obj.name);
});
//如果要进行资源释放管理 那么我们需要使用这种方式 要方便一些
//因为我们得到了返回值对象 就可以释放资源了
handle.Completed += (obj) =>
{
foreach (var item in obj.Result)
{
//print(item.name);
}
//释放资源
Addressables.Release(obj);
};
//注意:我们还是可以通过泛型类型,来筛选资源类型
根据多种信息加载对象
//参数一:想要加载资源的条件列表(资源名、Lable名)
//参数二:每个加载资源结束后会调用的函数,会把加载到的资源传入该函数中
//参数三:可寻址的合并模式,用于合并请求结果的选项。
//如果键(Cube,Red)映射到结果([1,2,3],[1,3,4]),数字代表不同的资源
//None:不发生合并,将使用第一组结果 结果为[1,2,3]
//UseFirst:应用第一组结果 结果为[1,2,3]
//Union:合并所有结果 结果为[1,2,3,4]
//Intersection:使用相交结果 结果为[1,3]
//参数四:如果为true表示当资源加载失败时,会自动将已加载的资源和依赖都释放掉
// 如果为false,需要自己手动来管理释放
List<string> strs = new List<string>() { "Mat", "Red" };
Addressables.LoadAssetsAsync<Object>(strs, (obj) => {
print(obj.name);
}, Addressables.MergeMode.Intersection);
//注意:我们还是可以通过泛型类型,来筛选资源类型
2、AddressableMgr
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class AddressableMgr
{
public static AddressableMgr instance = new AddressableMgr();
public static AddressableMgr Instance => instance;
// 有一个容帮助存储异步加载的返回值
public Dictionary<string, IEnumerator> resDic = new Dictionary<string, IEnumerator>();
private AddressableMgr() { }
public void LoadAssetAsync<T>(string name, Action<AsyncOperationHandle<T>> callback)
{
// 由于存在同名,不同类型资源区分加载,所以通过名字和类型进行拼接作为 Key
string keyName = name + "_" + typeof(T).Name;
AsyncOperationHandle<T> handle;
// 已经加载过该资源
if (resDic.ContainsKey(keyName))
{
// 获取异步加载返回的 handle
handle = (AsyncOperationHandle<T>)resDic[keyName];
if (handle.IsDone)
{
callback(handle);
}
// 还没有加载完成
else
{
// 如果还没有异步加载完成,只需要添加委托告诉完成后做什么
handle.Completed += (obj) =>
{
if (obj.Status == AsyncOperationStatus.Succeeded)
callback(obj);
};
}
return;
}
// 如果没有加载过该资源,直接进行异步加载并记录
handle = Addressables.LoadAssetAsync<T>(name);
handle.Completed += (obj) =>
{
if (obj.Status == AsyncOperationStatus.Succeeded)
callback(obj);
else
{
Debug.LogWarning(keyName + " load asset failed");
if (resDic.ContainsKey(keyName))
resDic.Remove(keyName);
}
};
resDic[keyName] = handle;
}
public void Release<T>(string name)
{
string keyName = name + "_" + typeof(T).Name;
if (resDic.ContainsKey(keyName))
{
AsyncOperationHandle<T> handle = (AsyncOperationHandle <T>)resDic[keyName];
Addressables.Release(handle);
resDic.Remove(keyName);
}
}
// 异步加载多个资源 或者 加载指定资源
private string FormatKeyName<T>(List<string> keys)
{
string keyName = "";
foreach (string key in keys)
keyName += key + "_";
keyName += typeof(T).Name;
return keyName;
}
public void LoadAssetAsync<T>(Addressables.MergeMode mode, Action<T> callBack, params string[] keys)
{
// 1.构建一个 keyName 之后存入到字典中
List<string> list = new List<string>(keys);
string keyName = FormatKeyName<T>(list);
// 2.判断是否存在已经加载过的内容
AsyncOperationHandle<IList<T>> handle;
if (resDic.ContainsKey(keyName))
{
handle = (AsyncOperationHandle<IList<T>>)resDic[keyName];
// 异步加载是否结束
if (handle.IsDone)
{
foreach(T item in handle.Result)
callBack(item);
}
else
{
handle.Completed += (obj) =>
{
if (obj.Status == AsyncOperationStatus.Succeeded)
{
foreach (T item in handle.Result)
callBack(item);
}
};
}
return;
}
handle = Addressables.LoadAssetsAsync<T>(list, callBack, mode);
handle.Completed += (obj) =>
{
if (obj.Status == AsyncOperationStatus.Failed)
{
Debug.LogWarning(keyName + " load asset failed");
if (resDic.ContainsKey(keyName))
resDic.Remove(keyName);
}
};
resDic.Add(keyName, handle);
}
public void LoadAssetAsync<T>(Addressables.MergeMode mode, Action<AsyncOperationHandle<IList<T>>> callBack, params string[] keys)
{
// 1.构建一个 keyName 之后存入到字典中
List<string> list = new List<string>(keys);
string keyName = FormatKeyName<T>(list);
// 2.判断是否存在已经加载过的内容
AsyncOperationHandle<IList<T>> handle;
if (resDic.ContainsKey(keyName))
{
handle = (AsyncOperationHandle<IList<T>>)resDic[keyName];
// 异步加载是否结束
if (handle.IsDone)
{
callBack(handle);
}
else
{
handle.Completed += (obj) =>
{
if (obj.Status == AsyncOperationStatus.Succeeded)
{
callBack(handle);
}
};
}
return;
}
handle = Addressables.LoadAssetsAsync<T>(list, null, mode);
handle.Completed += (obj) =>
{
if (obj.Status == AsyncOperationStatus.Failed)
{
Debug.LogWarning(keyName + " load asset failed");
if (resDic.ContainsKey(keyName))
resDic.Remove(keyName);
}
else
{
callBack(handle);
}
};
resDic.Add(keyName, handle);
}
public void Release<T>(params string[] keys)
{
List<string> list = new List<string>(keys);
string keyName = FormatKeyName<T>(list);
if ( resDic.ContainsKey(keyName))
{
AsyncOperationHandle<IList<T>> handle = (AsyncOperationHandle<IList<T>>)resDic[keyName];
Addressables.Release(handle);
resDic.Remove(keyName);
}
}
public void Clear()
{
resDic.Clear();
AssetBundle.UnloadAllAssetBundles(true);
Resources.UnloadUnusedAssets();
GC.Collect();
}
}