单个包的加载,需要记录AB包中资源的标签和预制体名; 初始化依赖; 加载AB包; 加载资源; 实例化游戏物体; 释放资源。
主类
public class Main : MonoBehaviour
{
[Header("标签名:")]
public string assetBundle;
[Header("预制体名:")]
public string prefabName;
void Awake()
{
//初始化
AssetBundleLoadMgr.Instance.Init();
}
void LoadAsset()
{
//加载预设
GameObject prefab = AssetBundleLoadMgr.Instance.LoadAsset<GameObject>(assetBundle, prefabName);
//实例化预设
Instantiate(prefab);
AssetBundleLoadMgr.Instance.RealeaseAssetBundle(assetBundle);
}
void OnGUI()
{
if (GUI.Button(new Rect(100, 100, 100, 50), "LoadAsset"))
{
LoadAsset();
}
}
}
单例类
public class AssetBundleLoadMgr : MonoBehaviour
{
/// <summary>
/// 缓存加载的AssetBundle,防止多次加载
/// </summary>
private Dictionary<string,AssetBundle> m_abDic= new Dictionary<string,AssetBundle>();
///<summary>
///保存各个AssetBundle的依赖信息
/// </summary>
private static AssetBundleManifest m_mainfest;
/// <summary>
/// 单例
/// </summary>
private static AssetBundleLoadMgr instance;
public static AssetBundleLoadMgr Instance
{
get
{
if(null==instance) instance = new AssetBundleLoadMgr();
return instance;
}
}
///<summary>
///初始化,加载AssetBundleManifest,方便后续查找依赖
/// </summary>
public static void Init()
{
string streamingAssetsAbPath = Path.Combine(Application.streamingAssetsPath, "StandaloneWindows");
AssetBundle streamingAssetsAb=AssetBundle.LoadFromFile(streamingAssetsAbPath);
m_mainfest = streamingAssetsAb.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
}
/// <summary>
/// 加载AssetBundle
/// </summary>
/// <param name="name">AssetBundle名称</param>
/// <returns></returns>
public AssetBundle LoadAssetBundle(string abName)
{
AssetBundle ab = null;
if (!m_abDic.ContainsKey(abName))
{
string abResPath = Path.Combine(Application.streamingAssetsPath, abName);
ab = AssetBundle.LoadFromFile(abResPath);
m_abDic[abName] = ab;
}
else
{
ab = m_abDic[abName];
}
return ab;
}
///<summary>
///从AssetBundle加载资源
/// </summary>
public T LoadAsset<T>(string abName,string assetName) where T : Object
{
AssetBundle ab = LoadAssetBundle(abName);
T t=ab.LoadAsset<T>(assetName);
return t;
}
///<summary>
///释放AssetBundle包的资源
/// </summary>
public void RealeaseAssetBundle(string abName)
{
foreach (AssetBundle bundle in AssetBundle.GetAllLoadedAssetBundles())
{
if (bundle.name == abName)
{
bundle.Unload(false);
}
}
}
}
资源复用
实际项目中会有多个预制体有相同的部分,如果将相同部分依次压缩,会造成资源的浪费。为了避免资源的浪费,可以将共同依赖的部分单独作为一个AssetBundle进行压缩,其它不同的部分再各自压缩。这样,不同的部分和共同的部分就形成了依赖关系。在做AB包加载的时候,就需要先加载依赖,再加载不同的部分,不然就会造成资源的丢失。