image.png

预备部分

实现部分

(1)加载方式一(未优化)

①同步加载方式一

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>
  5. /// 知识点
  6. /// 1.AB包先关的API
  7. /// 2.单例模式
  8. /// 3.委托 -> Lambda表达式
  9. /// 4.协程
  10. /// 5.字典
  11. /// </summary>
  12. public class ABMgr : SingletonAutoMono<ABMgr>
  13. {
  14. //AB包管理器 目的是:让外部更方便的进行资源加载
  15. //主包
  16. private AssetBundle mainAB = null;
  17. //依赖包获取用的配置文件
  18. private AssetBundleManifest manifest = null;
  19. /// <summary>
  20. /// AB包存放路径 方便修改
  21. /// </summary>
  22. private string pathUrl
  23. {
  24. get
  25. {
  26. return Application.streamingAssetsPath + "/";
  27. }
  28. }
  29. /// <summary>
  30. /// 主包名 方便修改
  31. /// </summary>
  32. private string MainABName
  33. {
  34. get
  35. {
  36. #if UNITY_IOS
  37. return "IOS";
  38. #elif UNITY_ANDROID
  39. return "Android";
  40. #else
  41. return "PC";
  42. }
  43. }
  44. //AB包不能够重复加载 重复加载会报错
  45. //字典 用字典来存储 加载过的AB包
  46. private Dictionary<string,AssetBundle> abDic = new Dictionary<string, AssetBundle>();//存储AB包容器
  47. //同步加载
  48. public Object LoadRes(string abName,string resName)
  49. {
  50. //加载AB包
  51. if(mainAB == null)
  52. {
  53. mainAB = AssetBundle.LoadFromFile(pathUrl + "PC");
  54. manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");//得到主包的配置文件
  55. }
  56. //获取依赖包相关信息
  57. AssetBundle ab;
  58. string[] strs = manifest.GetAllDependencies(abName);//通过配置文件得到相关依赖包
  59. for (int i = 0; i < strs.Length; i++)
  60. {
  61. //判断包是否加载过
  62. if(abDic.ContainsKey(strs[i]))
  63. {
  64. ab = AssetBundle.LoadFromFile(pathUrl + strs[i]);
  65. abDic.Add(strs[i], ab);
  66. }
  67. }
  68. //加载资源来源包(如果没有加载过,再加载)
  69. if (!abDic.ContainsKey(abName))
  70. {
  71. ab = AssetBundle.LoadFromFile(pathUrl + abName);
  72. }
  73. //加载资源
  74. return abDic[abName].LoadAsset(resName);
  75. }
  76. }

②具体实现

  1. void Start()
  2. {
  3. Object obj = ABMgr.GetInstance().LoadRes("model","Cube");
  4. Instantiate(obj);//一定要记得实例化
  5. }

(2)加载方式一(添加优化)

  1. //为了外面方便 在加载资源时 判断一下 资源是不是GameObject
  2. //如果是 直接实例化了 再返回给外部
  3. Object obj = abDic[abName].LoadAsset(resName);
  4. if (obj is GameObject){
  5. return Instantiate(obj);
  6. }
  7. else return obj;
  1. Object obj = ABMgr.GetInstance().LoadRes("model","Cube") as GameObject;
  2. obj.transform.position = Vector3.up();//得到后直接使用

(3)加载方式二(指定类型加载)

  1. Object obj = ABMgr.GetInstance().LoadRes("model","Cube",typeof(GameObject)) as GameObject;
  2. obj.transform.position = Vector3.up();//得到后直接使用

(4)加载方式二(指定泛型加载)

  1. Object obj = ABMgr.GetInstance().LoadRes<GameObject>("model","Cube");
  2. obj.transform.position = Vector3.up();//得到后直接使用

(5)以上方法汇总

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>
  5. /// 知识点
  6. /// 1.AB包先关的API
  7. /// 2.单例模式
  8. /// 3.委托 -> Lambda表达式
  9. /// 4.协程
  10. /// 5.字典
  11. /// </summary>
  12. public class ABMgr : SingletonAutoMono<ABMgr>
  13. {
  14. //AB包管理器 目的是:让外部更方便的进行资源加载
  15. //主包
  16. private AssetBundle mainAB = null;
  17. //依赖包获取用的配置文件
  18. private AssetBundleManifest manifest = null;
  19. /// <summary>
  20. /// AB包存放路径 方便修改
  21. /// </summary>
  22. private string pathUrl
  23. {
  24. get
  25. {
  26. return Application.streamingAssetsPath + "/";
  27. }
  28. }
  29. /// <summary>
  30. /// 主包名 方便修改
  31. /// </summary>
  32. private string MainABName
  33. {
  34. get
  35. {
  36. #if UNITY_IOS
  37. return "IOS";
  38. #elif UNITY_ANDROID
  39. return "Android";
  40. #else
  41. return "PC";
  42. }
  43. }
  44. //AB包不能够重复加载 重复加载会报错
  45. //字典 用字典来存储 加载过的AB包
  46. private Dictionary<string,AssetBundle> abDic = new Dictionary<string, AssetBundle>();//存储AB包容器
  47. /// <summary>
  48. /// 加载AB包
  49. /// </summary>
  50. /// <param name="abName"></param>
  51. private void LoadAB(string abName)
  52. {
  53. //加载AB包
  54. if (mainAB == null)
  55. {
  56. mainAB = AssetBundle.LoadFromFile(pathUrl + "PC");
  57. manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");//得到主包的配置文件
  58. }
  59. //获取依赖包相关信息
  60. AssetBundle ab;
  61. string[] strs = manifest.GetAllDependencies(abName);//通过配置文件得到相关依赖包
  62. for (int i = 0; i < strs.Length; i++)
  63. {
  64. //判断包是否加载过
  65. if (abDic.ContainsKey(strs[i]))
  66. {
  67. ab = AssetBundle.LoadFromFile(pathUrl + strs[i]);
  68. abDic.Add(strs[i], ab);
  69. }
  70. }
  71. //加载资源来源包(如果没有加载过,再加载)
  72. if (!abDic.ContainsKey(abName))
  73. {
  74. ab = AssetBundle.LoadFromFile(pathUrl + abName);
  75. }
  76. }
  77. //同步加载 不指定类型
  78. public Object LoadRes(string abName,string resName)
  79. {
  80. LoadAB(abName);//加载AB包
  81. //为了外面方便 在加载资源时 判断一下 资源是不是GameObject
  82. //如果是 直接实例化了 再返回给外部
  83. Object obj = abDic[abName].LoadAsset(resName);
  84. if (obj is GameObject){
  85. return Instantiate(obj);
  86. }
  87. else return obj;
  88. }
  89. //同步加载 根据type指定类型
  90. public Object LoadRes(string abName, string resName,System.Type type)
  91. {
  92. LoadAB(abName);//加载AB包
  93. //为了外面方便 在加载资源时 判断一下 资源是不是GameObject
  94. //如果是 直接实例化了 再返回给外部
  95. Object obj = abDic[abName].LoadAsset(resName,type);
  96. if (obj is GameObject)
  97. {
  98. return Instantiate(obj);
  99. }
  100. else return obj;
  101. }
  102. //同步加载 根据泛型指定类型
  103. public T LoadRes<T>(string abName, string resName) where T:Object
  104. {
  105. LoadAB(abName);//加载AB包
  106. //为了外面方便 在加载资源时 判断一下 资源是不是GameObject
  107. //如果是 直接实例化了 再返回给外部
  108. T obj = abDic[abName].LoadAsset<T>(resName);
  109. if (obj is GameObject)
  110. {
  111. return Instantiate(obj);
  112. }
  113. else return obj;
  114. }
  115. //单个包卸载
  116. public void UnLoad(string abName)
  117. {
  118. if(abDic.ContainsKey(abName))
  119. {
  120. abDic[abName].Unload(false);
  121. abDic.Remove(abName);
  122. }
  123. }
  124. //所有包的卸载
  125. public void ClearAB()
  126. {
  127. AssetBundle.UnloadAllAssetBundles(false);
  128. abDic.Clear();
  129. mainAB = null;
  130. manifest = null;
  131. }
  132. }