1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class ABAsyncTest : MonoBehaviour
    5. {
    6. void Start()
    7. {
    8. //第一种
    9. ABMgr.GetInstance().LoadResAsync("model", "Cube", (obj) =>
    10. {
    11. (obj as GameObject).transform.position = -Vector3.up;
    12. });
    13. //第二种(Type方式)
    14. ABMgr.GetInstance().LoadResAsync("model", "Cube",typeof(GameObject), (obj) =>
    15. {
    16. (obj as GameObject).transform.position = -Vector3.up;
    17. });
    18. //第三种(泛型方式)
    19. ABMgr.GetInstance().LoadResAsync<GameObject>("model", "Cube", (obj) =>
    20. {
    21. obj.transform.position = -Vector3.up;
    22. });
    23. }
    24. }
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. /// <summary>
    4. /// 知识点
    5. /// 1.AB包先关的API
    6. /// 2.单例模式
    7. /// 3.委托 -> Lambda表达式
    8. /// 4.协程
    9. /// 5.字典
    10. /// </summary>
    11. public class ABMgr : SingletonAutoMono<ABMgr>
    12. {
    13. //AB包管理器 目的是:让外部更方便的进行资源加载
    14. //主包
    15. private AssetBundle mainAB = null;
    16. //依赖包获取用的配置文件
    17. private AssetBundleManifest manifest = null;
    18. /// <summary>
    19. /// AB包存放路径 方便修改
    20. /// </summary>
    21. private string pathUrl
    22. {
    23. get
    24. {
    25. return Application.streamingAssetsPath + "/";
    26. }
    27. }
    28. /// <summary>
    29. /// 主包名 方便修改
    30. /// </summary>
    31. private string MainABName
    32. {
    33. get
    34. {
    35. #if UNITY_IOS
    36. return "IOS";
    37. #elif UNITY_ANDROID
    38. return "Android";
    39. #else
    40. return "PC";
    41. }
    42. }
    43. //AB包不能够重复加载 重复加载会报错
    44. //字典 用字典来存储 加载过的AB包
    45. private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();//存储AB包容器
    46. /// <summary>
    47. /// 加载AB包
    48. /// </summary>
    49. /// <param name="abName"></param>
    50. private void LoadAB(string abName)
    51. {
    52. //加载AB包
    53. if (mainAB == null)
    54. {
    55. mainAB = AssetBundle.LoadFromFile(pathUrl + "PC");
    56. manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");//得到主包的配置文件
    57. }
    58. //获取依赖包相关信息
    59. AssetBundle ab;
    60. string[] strs = manifest.GetAllDependencies(abName);//通过配置文件得到相关依赖包
    61. for (int i = 0; i < strs.Length; i++)
    62. {
    63. //判断包是否加载过
    64. if (abDic.ContainsKey(strs[i]))
    65. {
    66. ab = AssetBundle.LoadFromFile(pathUrl + strs[i]);
    67. abDic.Add(strs[i], ab);
    68. }
    69. }
    70. //加载资源来源包(如果没有加载过,再加载)
    71. if (!abDic.ContainsKey(abName))
    72. {
    73. ab = AssetBundle.LoadFromFile(pathUrl + abName);
    74. }
    75. }
    76. //异步加载的方法
    77. //这里的异步加载 AB包并没有使用异步加载
    78. //知识从AB包中 加载资源时 使用异步
    79. /// <summary>
    80. /// 根据名字异步加载资源
    81. /// </summary>
    82. /// <param name="abName"></param>
    83. /// <param name="resName"></param>
    84. /// <param name="callBack"></param>
    85. private void LoadResAsync(string abName, string resName,UnityAction<Object> callBack)//提供给外部方法,用于启动协程
    86. {
    87. StartCoroutine(ReallyLoadResAsync(abName,resName,callBack));
    88. }
    89. private IEnumerator ReallyLoadResAsync(string abName,string resName,UnityAction<Object> callBack)//正儿八经要用到的协程
    90. {
    91. AssetBundleRequest abr = abDic[abName].LoadAssetAsync(resName);
    92. //异步加载结束后 通过委托 传递给外部 外部来使用
    93. if(abr.asset == null )
    94. if (abr.asset is GameObject)
    95. {
    96. callBack(Instantiate(abr.asset));
    97. }
    98. else callBack(abr.asset);
    99. yield return null;
    100. }
    101. /// <summary>
    102. /// 根据Type异步加载资源
    103. /// </summary>
    104. /// <param name="abName"></param>
    105. private void LoadResAsync(string abName, string resName, System.Type type,UnityAction<Object> callBack)//提供给外部方法,用于启动协程
    106. {
    107. StartCoroutine(ReallyLoadResAsync(abName, resName, callBack));
    108. }
    109. private IEnumerator ReallyLoadResAsync(string abName, string resName, System.Type type, UnityAction<Object> callBack)//正儿八经要用到的协程
    110. {
    111. AssetBundleRequest abr = abDic[abName].LoadAssetAsync(resName,type);
    112. //异步加载结束后 通过委托 传递给外部 外部来使用
    113. if (abr.asset == null)
    114. if (abr.asset is GameObject)
    115. {
    116. callBack(Instantiate(abr.asset));
    117. }
    118. else callBack(abr.asset);
    119. yield return null;
    120. }
    121. /// <summary>
    122. /// 根据泛型异步加载
    123. /// </summary>
    124. /// <param name="abName"></param>
    125. private void LoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T:Object//提供给外部方法,用于启动协程
    126. {
    127. StartCoroutine(ReallyLoadResAsync<T>(abName, resName, callBack));
    128. }
    129. private IEnumerator ReallyLoadResAsync<T>(string abName, string resName, UnityAction<T> callBack)//正儿八经要用到的协程
    130. {
    131. AssetBundleRequest abr = abDic[abName].LoadAssetAsync(resName);
    132. //异步加载结束后 通过委托 传递给外部 外部来使用
    133. if (abr.asset == null)
    134. if (abr.asset is GameObject)
    135. {
    136. callBack(Instantiate(abr.asset) as T);
    137. }
    138. else callBack(abr.asset);
    139. yield return null;
    140. }
    141. //单个包卸载
    142. public void UnLoad(string abName)
    143. {
    144. if (abDic.ContainsKey(abName))
    145. {
    146. abDic[abName].Unload(false);
    147. abDic.Remove(abName);
    148. }
    149. }
    150. //所有包的卸载
    151. public void ClearAB()
    152. {
    153. AssetBundle.UnloadAllAssetBundles(false);
    154. abDic.Clear();
    155. mainAB = null;
    156. manifest = null;
    157. }
    158. }