AssetBundleLoadManager.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using Core.AssetLoadTool.Asset;
  6. using Fort23.Core;
  7. using Fort23.UTool;
  8. #if !COMBAT_SERVER
  9. using UnityEngine;
  10. using UnityEngine.Networking;
  11. using Object = UnityEngine.Object;
  12. using Utility;
  13. public class AssetBundleLoadManager : Singleton<AssetBundleLoadManager>
  14. {
  15. public BundleLoadType BundleLoadType;
  16. public string h5Url;
  17. public bool UnloadType = true;
  18. public bool stopUpdate;
  19. private string m_rootStreamingURL;
  20. public string RootStreamingURL
  21. {
  22. get { return m_rootStreamingURL; }
  23. }
  24. private string m_rootStreamingBundleURL;
  25. public string RootStreamingBundleURL
  26. {
  27. get { return m_rootStreamingBundleURL; }
  28. }
  29. private string m_rootPersistentBundleURL;
  30. public string RootPersistentBundleURL
  31. {
  32. get { return m_rootPersistentBundleURL; }
  33. }
  34. public string manifestName
  35. {
  36. get { return m_manifestName; }
  37. }
  38. private string m_manifestName;
  39. private string m_globalConfigName;
  40. private string m_buildNoName;
  41. private string m_assetConfigName;
  42. public float gcTime;
  43. public Map<string, AssetInfo> assetToBundleDict = new Map<string, AssetInfo>();
  44. private AssetBundleManifest assetBundleManifest = null;
  45. private int index = 0;
  46. private System.Action loadEndCallBack;
  47. public Map<AssetInfo, AssetLoadTaskBasic> m_currLoadAsset = new Map<AssetInfo, AssetLoadTaskBasic>();
  48. public Map<string, BundleLoadBasic> m_currLoadBundle = new Map<string, BundleLoadBasic>();
  49. public bool isSceneLoad;
  50. private List<BundleLoadBasic> bundleUnloadBuffer = new List<BundleLoadBasic>();
  51. public List<BundleLoadBasic> dependenciesBuffer = new List<BundleLoadBasic>();
  52. public bool isUnload;
  53. public System.Action<string> onLoadAsset;
  54. public AssetBundleLoadManager()
  55. {
  56. SetFileRoot();
  57. }
  58. public async CTask InitAssetsManager(System.Action loadEndCallBack)
  59. {
  60. // Ctask
  61. CTask cTask = CTask.Create(false);
  62. LogTool.Log("kaishijiazai asset");
  63. this.loadEndCallBack = delegate
  64. {
  65. cTask.SetResult();
  66. loadEndCallBack?.Invoke();
  67. };
  68. index = 0;
  69. //Load assetconfig file.
  70. LoadAssetConfig(null);
  71. //Load manifest file.
  72. LoadManifest();
  73. await cTask;
  74. }
  75. public void UnloadBundleBuffer()
  76. {
  77. LogTool.Log("卸载数据");
  78. for (int i = 0; i < bundleUnloadBuffer.Count; i++)
  79. {
  80. bundleUnloadBuffer[i].UnloadBundle();
  81. }
  82. bundleUnloadBuffer.Clear();
  83. }
  84. public void CallBackLoadEnd()
  85. {
  86. index++;
  87. if (index >= 2)
  88. {
  89. loadEndCallBack();
  90. }
  91. }
  92. private void SetFileRoot()
  93. {
  94. m_rootStreamingURL = Application.streamingAssetsPath;
  95. m_rootStreamingBundleURL = m_rootStreamingURL + "/Bundle/";
  96. m_rootPersistentBundleURL = Application.persistentDataPath + "/Bundle/";
  97. #if UNITY_EDITOR
  98. m_assetConfigName = Application.streamingAssetsPath +
  99. "/assetConfig.txt";
  100. #elif UNITY_IPHONE
  101. m_rootStreamingURL = "file://" + m_rootStreamingURL;
  102. m_rootStreamingBundleURL = "file://" + m_rootStreamingBundleURL;
  103. m_assetConfigName = m_rootPersistentBundleURL +
  104. "assetConfig.txt";
  105. #else
  106. m_assetConfigName = m_rootPersistentBundleURL +
  107. "assetConfig.txt";
  108. #endif
  109. m_manifestName = "UnityBundle";
  110. //Temp path. When version update is ready, path will be persistentPath and streamingPath.
  111. // m_rootpersistentBundleURL = Application.persistentDataPath + "/BundlAsset/";
  112. }
  113. public void LoadAssetConfig(System.Action callBack)
  114. {
  115. DoLoadingAssetConfig(m_assetConfigName, callBack);
  116. }
  117. private void DoLoadingAssetConfig(string url, System.Action callBack)
  118. {
  119. assetToBundleDict.Clear();
  120. if (BundleLoadType != BundleLoadType.H5 && File.Exists(url))
  121. {
  122. Debug.Log("URL:" + url);
  123. string data = File.ReadAllText(url);
  124. LoadPackedInfo(data, callBack);
  125. }
  126. else
  127. {
  128. // url = m_rootStreamingURL +
  129. if (BundleLoadType != BundleLoadType.H5)
  130. {
  131. url = m_rootStreamingBundleURL + "assetConfig.txt";
  132. }
  133. else
  134. {
  135. url = h5Url + "assetConfig.txt";
  136. }
  137. Debug.Log("URL22:" + url);
  138. Uri uri = new Uri(url);
  139. UnityWebRequest unityWebRequest = UnityWebRequest.Get(uri);
  140. UnityWebRequestAsyncOperation webRequestAsyncOperation = unityWebRequest.SendWebRequest();
  141. webRequestAsyncOperation.completed += delegate(AsyncOperation operation)
  142. {
  143. if (!string.IsNullOrEmpty(webRequestAsyncOperation.webRequest.downloadHandler.error))
  144. {
  145. LogTool.Error(Application.streamingAssetsPath + "m_assetConfigName buchunzai" + m_assetConfigName);
  146. LogTool.Error(webRequestAsyncOperation.webRequest.downloadHandler.error);
  147. }
  148. else
  149. {
  150. LoadPackedInfo(webRequestAsyncOperation.webRequest.downloadHandler.text, callBack);
  151. }
  152. };
  153. }
  154. return;
  155. }
  156. private void LoadPackedInfo(string json, System.Action callBack)
  157. {
  158. // Debug.Log(json);
  159. AllPackedAssetsInfo allPackedInfo = JsonManager.FromJson<AllPackedAssetsInfo>(json);
  160. Debug.Log(allPackedInfo != null);
  161. Debug.Log(allPackedInfo.assetsList.Count);
  162. for (int i = 0; i < allPackedInfo.assetsList.Count; i++)
  163. {
  164. AssetInfo assetInfo = allPackedInfo.assetsList[i];
  165. if (assetInfo != null)
  166. {
  167. assetToBundleDict.Add(assetInfo.name, assetInfo);
  168. }
  169. }
  170. if (callBack != null)
  171. callBack();
  172. CallBackLoadEnd();
  173. }
  174. private void LoadManifest()
  175. {
  176. DoLoadingManifest();
  177. }
  178. private void DoLoadingManifest()
  179. {
  180. string url = RootPersistentBundleURL + m_manifestName;
  181. if (BundleLoadType!=BundleLoadType.H5&&!File.Exists(url))
  182. {
  183. url = Application.streamingAssetsPath + "/Bundle/" + m_manifestName;
  184. }
  185. if (BundleLoadType == BundleLoadType.LocalAsset)
  186. {
  187. CallBackLoadEnd();
  188. return;
  189. }
  190. if (BundleLoadType == BundleLoadType.H5)
  191. {
  192. url=h5Url+m_manifestName;
  193. }
  194. Debug.Log(url);
  195. UnityWebRequest webRequest= UnityWebRequestAssetBundle.GetAssetBundle(url);
  196. UnityWebRequestAsyncOperation webRequestAsyncOperation= webRequest.SendWebRequest();
  197. // AssetBundleCreateRequest bundlReq = AssetBundle.LoadFromFileAsync(url);
  198. webRequestAsyncOperation.completed += delegate(AsyncOperation operation)
  199. {
  200. DownloadHandlerAssetBundle downloadHandler= webRequest.downloadHandler as DownloadHandlerAssetBundle;
  201. assetBundleManifest = downloadHandler.assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
  202. if (assetBundleManifest != null)
  203. {
  204. LogTool.Log("AssetBundleManifest jizaiwancheng");
  205. }
  206. downloadHandler.assetBundle.Unload(false);
  207. CallBackLoadEnd();
  208. };
  209. }
  210. public string[] GetBundleDependencies(string bundleName)
  211. {
  212. if (assetBundleManifest == null)
  213. {
  214. return null;
  215. }
  216. return assetBundleManifest.GetDirectDependencies(bundleName);
  217. }
  218. public async CTask<AssetHandle> LoadAssetAsyncTask<T>(string assetName,
  219. System.Action<AssetHandle> callBack = null, Clock clock = null, bool isUseSynchronous = false) where T : Object
  220. {
  221. onLoadAsset?.Invoke(assetName);
  222. //临时使用到007的bundle加载,现在这个bundel卸载有遗漏,后面有时间了在改
  223. CTask task = CTask.Create(false);
  224. AssetHandle obj = null;
  225. LoadAssetAsync<T>(assetName, delegate(AssetHandle o, object o1)
  226. {
  227. if (o != null)
  228. {
  229. obj = o;
  230. }
  231. task.SetResult();
  232. }, clock, isUseSynchronous);
  233. await task;
  234. // TODO 暂时去掉,不知道会不会有影响
  235. // await TimerComponent.Instance.WaitFrameAsync();
  236. callBack?.Invoke(obj);
  237. return obj;
  238. }
  239. private void LoadAssetAsync<T>(string assetName, System.Action<AssetHandle, object> callBack, Clock clock = null,
  240. object userData = null, bool isUseSynchronous = false) where T : Object
  241. {
  242. if (!assetToBundleDict.TryGetValue(assetName, out AssetInfo assetInfo))
  243. {
  244. callBack?.Invoke(null, userData);
  245. Debug.LogWarning("没找到资源" + assetName);
  246. return;
  247. }
  248. LoadAssetCallBackData loadAssetCallBackData = new LoadAssetCallBackData();
  249. loadAssetCallBackData.loadEndCallBack = callBack;
  250. loadAssetCallBackData.userData = userData;
  251. loadAssetCallBackData.Clock = clock;
  252. loadAssetCallBackData.isUseSynchronous = isUseSynchronous;
  253. AssetLoadTaskBasic assetLoad = null;
  254. if (!m_currLoadAsset.TryGetValue(assetInfo, out assetLoad))
  255. {
  256. assetLoad = CreateAssetTaskBasic();
  257. assetLoad.InitAsset<T>(assetInfo, UnloadType, loadAssetCallBackData);
  258. m_currLoadAsset.Add(assetInfo, assetLoad);
  259. }
  260. else
  261. {
  262. assetLoad.AddCallBack<T>(loadAssetCallBackData);
  263. }
  264. }
  265. protected AssetLoadTaskBasic CreateAssetTaskBasic()
  266. {
  267. switch (BundleLoadType)
  268. {
  269. case BundleLoadType.LocalAsset:
  270. return new LocalAssetLoadTask();
  271. break;
  272. case BundleLoadType.LocalBundle:
  273. return new BundleAssetLoadTask();
  274. break;
  275. case BundleLoadType.H5:
  276. return new BundleAssetLoadTask();
  277. break;
  278. }
  279. LogTool.Error("加载模式不存在" + BundleLoadType);
  280. return null;
  281. }
  282. protected BundleLoadBasic CreateBundleTaskBasic()
  283. {
  284. switch (BundleLoadType)
  285. {
  286. case BundleLoadType.LocalAsset:
  287. break;
  288. case BundleLoadType.LocalBundle:
  289. return new LocalBundleLoadTask();
  290. break;
  291. case BundleLoadType.H5:
  292. return new H5BundleLoadTask();
  293. break;
  294. }
  295. LogTool.Error("加载模式不存在" + BundleLoadType);
  296. return null;
  297. }
  298. public BundleLoadBasic AddBundleTask(string bundleName, System.Action<BundleLoadBasic, object> callBack,
  299. LoadTaskBasic loadTaskBasic)
  300. {
  301. BundleLoadBasic bundleLoadTask = null;
  302. if (m_currLoadBundle.ContainsKey(bundleName))
  303. {
  304. bundleLoadTask = m_currLoadBundle[bundleName];
  305. }
  306. if (bundleLoadTask == null)
  307. {
  308. bundleLoadTask = CreateBundleTaskBasic();
  309. //AssetInfo bundleInfo = assetToBundleDict[assetName];
  310. m_currLoadBundle.Add(bundleName, bundleLoadTask);
  311. bundleLoadTask.InitBundle(bundleName, UnloadType, callBack);
  312. bundleLoadTask.AddOwnTask(loadTaskBasic);
  313. }
  314. else
  315. {
  316. bundleLoadTask.AddOwnTask(loadTaskBasic);
  317. bundleLoadTask.AddCallBack(callBack);
  318. }
  319. return bundleLoadTask;
  320. }
  321. public string GetBudnleInfo()
  322. {
  323. return $"当前拥有资源数:{m_currLoadAsset.Count} bundle数:{m_currLoadBundle.Count}";
  324. }
  325. public void UpdateBundle()
  326. {
  327. if (stopUpdate)
  328. return;
  329. BundleLoadBasic[] depend = dependenciesBuffer.ToArray();
  330. for (int i = 0; i < depend.Length; i++)
  331. {
  332. if (depend[i].AwaitDependenceLoadEnd())
  333. {
  334. dependenciesBuffer.Remove(depend[i]);
  335. }
  336. }
  337. bool isShowDebug = Input.GetKeyUp(KeyCode.K);
  338. int count = 0;
  339. for (m_currLoadAsset.Begin(); m_currLoadAsset.Next();)
  340. {
  341. if (isShowDebug)
  342. {
  343. Debug.Log(m_currLoadAsset.Key.name + "____" + m_currLoadAsset.Value.HandCount);
  344. }
  345. count += m_currLoadAsset.Value.HandCount;
  346. m_currLoadAsset.Value.Update();
  347. }
  348. if (isShowDebug)
  349. {
  350. Debug.Log($"当前拥有资源数:{count} bundle数:{m_currLoadBundle.Count}");
  351. }
  352. }
  353. public void RemoveAssetTask(AssetInfo assetInfo)
  354. {
  355. if (m_currLoadAsset.ContainsKey(assetInfo))
  356. {
  357. m_currLoadAsset.Remove(assetInfo);
  358. }
  359. }
  360. public void RemoveBundleTask(BundleLoadBasic budnleLoadTask)
  361. {
  362. if (m_currLoadBundle.ContainsKey(budnleLoadTask.bundleName))
  363. {
  364. m_currLoadBundle.Remove(budnleLoadTask.bundleName);
  365. }
  366. }
  367. public void ClearUnusedBundles()
  368. {
  369. }
  370. public bool IsAssetInfo(string assetName)
  371. {
  372. return false;
  373. }
  374. }
  375. #endif