Unity 热更–AssetBundle学习笔记 1.0【AB包资源加载工具类的实现】

工具类封装

通过上文中对AB包加载API的了解和简单使用,对AB包资源加载的几种方法进行封装,将其写入单例类中,如代码展示。

确保每个AB资源包只加载一次:

在LoadAssetBundleManager 单例工具类中,首先提供基本的AB包及其AB包依赖包的加载方法,为保持AssetBundle只加载一次,使用DIctionary键值对来记录已经加载出的AB资源。

主包路径的灵活获取:

加载主包路径的获取,采用宏来对不同的打包平台来选择对应的主包名称。(可自行定义使用)

依赖包的加载:

通过加载主包中的AssetBundleManifest 来获取目标AB包的依赖AB包名称,根据名称进行逐个加载。

加载方法有异步和同步两种:

异步加载是在AB包获取之后进行的资源的异步加载,和同步加载一样有对加载函数进行3此重载。分别为根据名称加载,

泛型加载(C#中使用方便),根据类型加载(供Lua调用)。

卸载方法的实现:单个AB资源包卸载和所有资源包卸载两种方式。

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events;  namespace BaseFramework {     /// <summary>     /// 加载AssetBundle工具类 单例      /// </summary>     public class LoadAssetBundleManager: SingletonAutoMono<LoadAssetBundleManager>     {         //主AB包          private AssetBundle mainAssetBundle = null;         //包体依赖manifest          private AssetBundleManifest assetBundleManifest = null;                  //防止AB包重复加载 对已经加载的AB包存储         private Dictionary<string, AssetBundle> assetBundlesDic = new Dictionary<string, AssetBundle>();          //加载路径         private string pathAssetBundle         {             get             {                 return Application.streamingAssetsPath + "/";             }         }         //主包名称         private string mainAssetBundleName         {             get             { #if UnITY_IOS                 return "IOS"; #elif UNITY_ANDROID                 return "Android"; #else                 return "StandaloneWindows"; #endif             }         }          /// <summary>         /// 根据名称加载AB包 也会检查相关依赖包 进行加载         /// </summary>         /// <param name="assetBundleName">AB包的名称</param>         public void LoadAssetBundle(string assetBundleName)         {             if (!assetBundlesDic.ContainsKey(assetBundleName))             {                  AssetBundle resAssetBundle = AssetBundle.LoadFromFile(pathAssetBundle+assetBundleName);                  assetBundlesDic.Add(assetBundleName,resAssetBundle);             }             //加载主资源包 从主资源包中获取对manifest             if (mainAssetBundle == null)             {                 mainAssetBundle = AssetBundle.LoadFromFile(pathAssetBundle + mainAssetBundleName);                 assetBundleManifest = mainAssetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");             }             //加载目标资源包的依赖AB             string[] dependencies = assetBundleManifest.GetAllDependencies(assetBundleName);             foreach (var dependency in dependencies)             {                 AssetBundle currentAB = null;                 if (!assetBundlesDic.ContainsKey(dependency))                 {                     //加载依赖的ab包                     currentAB = AssetBundle.LoadFromFile(pathAssetBundle + dependency);                      assetBundlesDic.Add(dependency,currentAB);                 }             }         }          /// <summary>         /// 从AB包中获取具体资源         /// </summary>         /// <param name="abName">AB包名称</param>         /// <param name="resName">资源名称</param>         /// <returns>Object资源</returns>         public Object LoadResource(string abName, string resName)         {             LoadAssetBundle(abName);             Object resObj = null;             resObj = assetBundlesDic[abName].LoadAsset(resName);             return resObj;         }         /// <summary>         /// 泛型方法重载         /// </summary>         public T LoadResource<T>(string abName, string resName) where T:Object         {             LoadAssetBundle(abName);             T res = assetBundlesDic[abName].LoadAsset<T>(resName);             return res;         }         /// <summary>         /// 根据资源类型重载方法         /// </summary>         public Object LoadResource(string abName, string resName, System.Type type)         {             LoadAssetBundle(abName);             Object obj = assetBundlesDic[abName].LoadAsset(resName, type);             return obj;         }         //--------------------------------------------------------         //同步加载的AB包 异步加载res资源         public void LoadResourceAsync(string abName, string resName, UnityAction<Object> callback)         {             StartCoroutine(LoadResourceIEn(abName, resName, callback));         }         //异步加载协程         private IEnumerator LoadResourceIEn(string abName, string resName, UnityAction<Object> callback)         {             LoadAssetBundle(abName);             AssetBundleRequest request = assetBundlesDic[abName].LoadAssetAsync(resName);             yield return request;             callback(request.asset);         }         //根据泛型来异步加资源         public void LoadResourceAsync<T>(string abName, string resName, UnityAction<Object> callback) where  T : Object         {             StartCoroutine(LoadResourceIEn<T>(abName, resName, callback));         }         //异步加载协程         private IEnumerator LoadResourceIEn<T>(string abName, string resName, UnityAction<Object> callback) where T :Object         {             LoadAssetBundle(abName);             AssetBundleRequest request = assetBundlesDic[abName].LoadAssetAsync<T>(resName);             yield return request;             callback(request.asset);         }         //根据res类型异步加载资源         //根据泛型来异步加资源         public void LoadResourceAsync(string abName, string resName, System.Type type,UnityAction<Object> callback)          {             StartCoroutine(LoadResourceIEn(abName, resName, type, callback));         }         //异步加载协程         private IEnumerator LoadResourceIEn(string abName, string resName, System.Type type, UnityAction<Object> callback)          {             LoadAssetBundle(abName);             AssetBundleRequest request = assetBundlesDic[abName].LoadAssetAsync(resName,type);             yield return request;             callback(request.asset);         }         //资源包的卸载         public void UnLoadAssetBundle(string abName)         {             if (assetBundlesDic.ContainsKey(abName))             {                 assetBundlesDic[abName].Unload(false);                 assetBundlesDic.Remove(abName);             }         }         //卸载所有加载的资源包         public void UnLoadAllAssetBundle()         {             AssetBundle.UnloadAllAssetBundles(false);             assetBundlesDic.Clear();             mainAssetBundle = null;             assetBundleManifest = null;         }      } } 

该Manager继承的单例脚本:

using UnityEngine;  namespace BaseFramework {     public class SingletonAutoMono<T> : MonoBehaviour where T : MonoBehaviour     {         private static T instance;          public static T Instance()         {             if (instance == null)             {                 GameObject gameObject = new GameObject();                 gameObject.name = typeof(T).ToString();                 DontDestroyOnLoad(gameObject);                 instance = gameObject.AddComponent<T>();             }             return instance;         }      } } 

在测试脚本中我们使用6种不同的加载方式进行cube的加载,完成方法测试。

 //测试使用工具类加载             Object cube = LoadAssetBundleManager.Instance().LoadResource("model", "cube");             if (cube is GameObject)             {                 GameObject cube1 = cube as GameObject;                 cube1.transform.position = Vector3.up;                 Instantiate(cube1);             }             //异步加载             LoadAssetBundleManager.Instance().LoadResourceAsync("model", "cube", (obj) =>             {                 GameObject cube1 = obj as GameObject;                 cube1.transform.position = new Vector3(0,1.5f,0);                 Instantiate(cube1);             });                          //重新测试             //使用泛型             GameObject cube2 = LoadAssetBundleManager.Instance().LoadResource<GameObject>("model", "cube");             cube2.transform.position = Vector3.left;             Instantiate(cube2);                                    LoadAssetBundleManager.Instance().LoadResourceAsync<GameObject>("model", "cube", (obj) =>              {                  GameObject cube1 = obj as GameObject;                  cube1.transform.position = Vector3.right;                  Instantiate(cube1);              });                            //通过类型加载测试              GameObject cube3 = LoadAssetBundleManager.Instance().LoadResource("model", "cube",typeof(GameObject)) as GameObject;              cube3.transform.position = new Vector3(0,-1.5f,0);              Instantiate(cube3);               LoadAssetBundleManager.Instance().LoadResourceAsync("model", "cube",typeof(GameObject), (obj) =>              {                  GameObject cube1 = obj as GameObject;                  cube1.transform.position = Vector3.zero;                  Instantiate(cube1);              });              LoadAssetBundleManager.Instance().UnLoadAllAssetBundle(); 

Unity 热更--AssetBundle学习笔记 1.0【AB包资源加载工具类的实现】

发表评论

相关文章