BundleLoadBasic.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. using System.Collections.Generic;
  2. using Fort23.Core;
  3. using Fort23.UTool;
  4. using UnityEngine;
  5. using Utility;
  6. namespace Core.AssetLoadTool.Asset
  7. {
  8. public class BundleLoadBasic : LoadTaskBasic
  9. {
  10. public List<LoadTaskBasic> ownTask = new List<LoadTaskBasic>();
  11. protected string url;
  12. private float progress;
  13. protected object userData;
  14. private Map<string, LoadInfoAsset> _bundleAsset = new Map<string, LoadInfoAsset>();
  15. public AssetBundle currBundle
  16. {
  17. get { return _currBundle; }
  18. }
  19. protected AssetBundle _currBundle;
  20. protected System.Action<BundleLoadBasic, object> callBack;
  21. protected List<BundleLoadBasic> m_dependenceTasks = new List<BundleLoadBasic>();
  22. protected bool isAwaitDependencies;
  23. protected bool _isUnloadType;
  24. public string bundleName;
  25. public void InitBundle(string bundleName, bool isUnloadType, System.Action<BundleLoadBasic, object> callBack)
  26. {
  27. // Debug.Log("加载bunlde"+bundleName);
  28. _isUnloadType = isUnloadType;
  29. loadState = LoadState.Init;
  30. AddCallBack(callBack);
  31. this.bundleName = bundleName;
  32. LoadDependencies(bundleName);
  33. }
  34. public bool IsRepeat(string bundleName)
  35. {
  36. for (int i = 0; i < m_dependenceTasks.Count; i++)
  37. {
  38. BundleLoadBasic bundleLoadBasic = m_dependenceTasks[i];
  39. if (bundleLoadBasic.bundleName == bundleName)
  40. {
  41. return true;
  42. }
  43. else
  44. {
  45. bool isRepeat = bundleLoadBasic.IsRepeat(bundleName);
  46. if (isRepeat)
  47. {
  48. return true;
  49. }
  50. }
  51. }
  52. return false;
  53. }
  54. public void LoadDependencies(string bundleName)
  55. {
  56. string[] dependencies = AssetBundleLoadManager.Instance.GetBundleDependencies(bundleName);
  57. if (dependencies != null && dependencies.Length > 0)
  58. {
  59. m_dependenceTasks = new List<BundleLoadBasic>();
  60. for (int i = 0; i < dependencies.Length; i++)
  61. {
  62. string depBundleName = dependencies[i];
  63. BundleLoadBasic task = AssetBundleLoadManager.Instance.AddBundleTask(depBundleName, null, this);
  64. if (task.IsRepeat(bundleName))
  65. {
  66. LogTool.Error("重复加载依赖包" + depBundleName + " " + bundleName);
  67. continue;
  68. }
  69. m_dependenceTasks.Add(task);
  70. }
  71. isAwaitDependencies = true;
  72. loadState = LoadState.Await;
  73. AssetBundleLoadManager.Instance.dependenciesBuffer.Add(this);
  74. }
  75. else
  76. {
  77. loadState = LoadState.Load;
  78. StartLoad();
  79. }
  80. }
  81. public bool AwaitDependenceLoadEnd()
  82. {
  83. for (int i = 0; i < m_dependenceTasks.Count; i++)
  84. {
  85. if (!m_dependenceTasks[i].IsLoadEnd())
  86. {
  87. return false;
  88. }
  89. }
  90. AwaitDependenciesFinish();
  91. return true;
  92. }
  93. protected void AwaitDependenciesFinish()
  94. {
  95. isAwaitDependencies = false;
  96. if (loadState == LoadState.Await)
  97. {
  98. // loadState = LoadState.End;
  99. // callBack?.Invoke(this, userData);
  100. loadState = LoadState.Load;
  101. StartLoad();
  102. }
  103. }
  104. protected void LoadFinish(AssetBundle assetBundle)
  105. {
  106. _currBundle = assetBundle;
  107. if (_currBundle == null)
  108. {
  109. LogTool.Error("budnle空的" + url + "__" + bundleName);
  110. return;
  111. }
  112. // if (isAwaitDependencies)
  113. // {
  114. // loadState = LoadState.Await;
  115. // }
  116. // else
  117. {
  118. loadState = LoadState.End;
  119. callBack?.Invoke(this, userData);
  120. }
  121. }
  122. public void AddCallBack(System.Action<BundleLoadBasic, object> callBack)
  123. {
  124. if (loadState == LoadState.End)
  125. {
  126. if (callBack != null)
  127. {
  128. callBack(this, userData);
  129. }
  130. return;
  131. }
  132. this.callBack += callBack;
  133. }
  134. public void AddOwnTask(LoadTaskBasic taskBasic)
  135. {
  136. if (taskBasic == null)
  137. {
  138. return;
  139. }
  140. if (ownTask.Contains(taskBasic))
  141. {
  142. return;
  143. }
  144. ownTask.Add(taskBasic);
  145. }
  146. public void RemoveAsset(string assetName)
  147. {
  148. if (_bundleAsset.TryGetValue(assetName, out LoadInfoAsset loadInfoAsset))
  149. {
  150. loadInfoAsset.count--;
  151. }
  152. }
  153. public async CTask<T> LoadAsset<T>(string assetName) where T : Object
  154. {
  155. if (_bundleAsset.TryGetValue(assetName, out LoadInfoAsset loadInfoAsset))
  156. {
  157. loadInfoAsset.count++;
  158. if (loadInfoAsset.asset == null)
  159. {
  160. _bundleAsset.Remove(assetName);
  161. }
  162. else
  163. {
  164. return (T)loadInfoAsset.asset;
  165. }
  166. }
  167. if (_currBundle == null)
  168. {
  169. LogTool.Error("budnle已经空" + url + "__" + bundleName);
  170. return default;
  171. }
  172. using (await CoroutineLockComponent.Instance.Wait(assetName))
  173. {
  174. if (_bundleAsset.TryGetValue(assetName, out loadInfoAsset))
  175. {
  176. return (T)loadInfoAsset.asset;
  177. }
  178. CTask cTask = CTask.Create(false);
  179. loadInfoAsset = new LoadInfoAsset();
  180. AssetBundleRequest assetBundleRequest = _currBundle.LoadAssetAsync<T>(assetName);
  181. assetBundleRequest.completed += delegate(AsyncOperation obj)
  182. {
  183. loadInfoAsset.asset = assetBundleRequest.asset;
  184. loadInfoAsset.count = 1;
  185. _bundleAsset.Add(assetName, loadInfoAsset);
  186. cTask.SetResult();
  187. };
  188. // loadInfoAsset.asset = _currBundle.LoadAsset<T>(assetName);
  189. // loadInfoAsset.count = 1;
  190. await cTask;
  191. }
  192. return (T)loadInfoAsset.asset;
  193. }
  194. public void RemoveOwnTask(LoadTaskBasic taskBasic)
  195. {
  196. ownTask.Remove(taskBasic);
  197. UnloadBundle();
  198. }
  199. public void UnloadBundle()
  200. {
  201. if (ownTask.Count <= 0)
  202. {
  203. Dispose();
  204. }
  205. }
  206. private void Dispose()
  207. {
  208. if (loadState == LoadState.Load)
  209. {
  210. return;
  211. }
  212. for (_bundleAsset.Begin(); _bundleAsset.Next();)
  213. {
  214. if (_bundleAsset.Value.asset is GameObject)
  215. {
  216. Object.DestroyImmediate(_bundleAsset.Value.asset, true);
  217. }
  218. else
  219. {
  220. Resources.UnloadAsset(_bundleAsset.Value.asset);
  221. }
  222. }
  223. _bundleAsset.Clear();
  224. for (int i = 0; i < m_dependenceTasks.Count; i++)
  225. {
  226. m_dependenceTasks[i].RemoveOwnTask(this);
  227. }
  228. m_dependenceTasks.Clear();
  229. if (_currBundle != null)
  230. {
  231. // Debug.Log("卸载bunlde"+bundleName);
  232. _currBundle.Unload(_isUnloadType);
  233. _currBundle = null;
  234. }
  235. AssetBundleLoadManager.Instance.RemoveBundleTask(this);
  236. loadState = LoadState.Disposed;
  237. }
  238. }
  239. }