ResourcePackage.cs 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. using System;
  2. using System.Diagnostics;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine.SceneManagement;
  6. namespace YooAsset
  7. {
  8. public class ResourcePackage
  9. {
  10. private bool _isInitialize = false;
  11. private string _initializeError = string.Empty;
  12. private EOperationStatus _initializeStatus = EOperationStatus.None;
  13. private EPlayMode _playMode;
  14. private IBundleServices _bundleServices;
  15. private IPlayModeServices _playModeServices;
  16. internal IPlayModeServices PlayModeServices { get { return _playModeServices; } }
  17. private AssetSystemImpl _assetSystemImpl;
  18. /// <summary>
  19. /// 包裹名
  20. /// </summary>
  21. public string PackageName { private set; get; }
  22. /// <summary>
  23. /// 初始化状态
  24. /// </summary>
  25. public EOperationStatus InitializeStatus
  26. {
  27. get { return _initializeStatus; }
  28. }
  29. private ResourcePackage()
  30. {
  31. }
  32. internal ResourcePackage(string packageName)
  33. {
  34. PackageName = packageName;
  35. }
  36. /// <summary>
  37. /// 更新资源包裹
  38. /// </summary>
  39. internal void UpdatePackage()
  40. {
  41. if (_assetSystemImpl != null)
  42. _assetSystemImpl.Update();
  43. }
  44. /// <summary>
  45. /// 销毁资源包裹
  46. /// </summary>
  47. internal void DestroyPackage()
  48. {
  49. if (_isInitialize)
  50. {
  51. _isInitialize = false;
  52. _initializeError = string.Empty;
  53. _initializeStatus = EOperationStatus.None;
  54. _bundleServices = null;
  55. _playModeServices = null;
  56. if (_assetSystemImpl != null)
  57. {
  58. _assetSystemImpl.ForceUnloadAllAssets();
  59. _assetSystemImpl = null;
  60. }
  61. }
  62. }
  63. /// <summary>
  64. /// 异步初始化
  65. /// </summary>
  66. public InitializationOperation InitializeAsync(InitializeParameters parameters)
  67. {
  68. // 注意:WebGL平台因为网络原因可能会初始化失败!
  69. ResetInitializeAfterFailed();
  70. // 检测初始化参数合法性
  71. CheckInitializeParameters(parameters);
  72. // 重写持久化根目录
  73. var persistent = PersistentTools.GetOrCreatePersistent(PackageName);
  74. persistent.OverwriteRootDirectory(parameters.BuildinRootDirectory, parameters.SandboxRootDirectory);
  75. // 初始化资源系统
  76. InitializationOperation initializeOperation;
  77. _assetSystemImpl = new AssetSystemImpl();
  78. if (_playMode == EPlayMode.EditorSimulateMode)
  79. {
  80. var editorSimulateModeImpl = new EditorSimulateModeImpl();
  81. _bundleServices = editorSimulateModeImpl;
  82. _playModeServices = editorSimulateModeImpl;
  83. _assetSystemImpl.Initialize(PackageName, true,
  84. parameters.LoadingMaxTimeSlice, parameters.DownloadFailedTryAgain,
  85. parameters.DecryptionServices, _bundleServices);
  86. var initializeParameters = parameters as EditorSimulateModeParameters;
  87. initializeOperation = editorSimulateModeImpl.InitializeAsync(initializeParameters.SimulateManifestFilePath);
  88. }
  89. else if (_playMode == EPlayMode.OfflinePlayMode)
  90. {
  91. var offlinePlayModeImpl = new OfflinePlayModeImpl();
  92. _bundleServices = offlinePlayModeImpl;
  93. _playModeServices = offlinePlayModeImpl;
  94. _assetSystemImpl.Initialize(PackageName, false,
  95. parameters.LoadingMaxTimeSlice, parameters.DownloadFailedTryAgain,
  96. parameters.DecryptionServices, _bundleServices);
  97. var initializeParameters = parameters as OfflinePlayModeParameters;
  98. initializeOperation = offlinePlayModeImpl.InitializeAsync(PackageName);
  99. }
  100. else if (_playMode == EPlayMode.HostPlayMode)
  101. {
  102. var hostPlayModeImpl = new HostPlayModeImpl();
  103. _bundleServices = hostPlayModeImpl;
  104. _playModeServices = hostPlayModeImpl;
  105. _assetSystemImpl.Initialize(PackageName, false,
  106. parameters.LoadingMaxTimeSlice, parameters.DownloadFailedTryAgain,
  107. parameters.DecryptionServices, _bundleServices);
  108. var initializeParameters = parameters as HostPlayModeParameters;
  109. initializeOperation = hostPlayModeImpl.InitializeAsync(
  110. PackageName,
  111. initializeParameters.BuildinQueryServices,
  112. initializeParameters.DeliveryQueryServices,
  113. initializeParameters.RemoteServices
  114. );
  115. }
  116. else if (_playMode == EPlayMode.WebPlayMode)
  117. {
  118. var webPlayModeImpl = new WebPlayModeImpl();
  119. _bundleServices = webPlayModeImpl;
  120. _playModeServices = webPlayModeImpl;
  121. _assetSystemImpl.Initialize(PackageName, false,
  122. parameters.LoadingMaxTimeSlice, parameters.DownloadFailedTryAgain,
  123. parameters.DecryptionServices, _bundleServices);
  124. var initializeParameters = parameters as WebPlayModeParameters;
  125. initializeOperation = webPlayModeImpl.InitializeAsync(
  126. PackageName,
  127. initializeParameters.BuildinQueryServices,
  128. initializeParameters.RemoteServices
  129. );
  130. }
  131. else
  132. {
  133. throw new NotImplementedException();
  134. }
  135. // 监听初始化结果
  136. _isInitialize = true;
  137. initializeOperation.Completed += InitializeOperation_Completed;
  138. return initializeOperation;
  139. }
  140. private void ResetInitializeAfterFailed()
  141. {
  142. if (_isInitialize && _initializeStatus == EOperationStatus.Failed)
  143. {
  144. _isInitialize = false;
  145. _initializeStatus = EOperationStatus.None;
  146. _initializeError = string.Empty;
  147. _bundleServices = null;
  148. _playModeServices = null;
  149. _assetSystemImpl = null;
  150. }
  151. }
  152. private void CheckInitializeParameters(InitializeParameters parameters)
  153. {
  154. if (_isInitialize)
  155. throw new Exception($"{nameof(ResourcePackage)} is initialized yet.");
  156. if (parameters == null)
  157. throw new Exception($"{nameof(ResourcePackage)} create parameters is null.");
  158. #if !UNITY_EDITOR
  159. if (parameters is EditorSimulateModeParameters)
  160. throw new Exception($"Editor simulate mode only support unity editor.");
  161. #endif
  162. if (parameters is EditorSimulateModeParameters)
  163. {
  164. var editorSimulateModeParameters = parameters as EditorSimulateModeParameters;
  165. if (string.IsNullOrEmpty(editorSimulateModeParameters.SimulateManifestFilePath))
  166. throw new Exception($"{nameof(editorSimulateModeParameters.SimulateManifestFilePath)} is null or empty.");
  167. }
  168. if (parameters is HostPlayModeParameters)
  169. {
  170. var hostPlayModeParameters = parameters as HostPlayModeParameters;
  171. if (hostPlayModeParameters.BuildinQueryServices == null)
  172. throw new Exception($"{nameof(IBuildinQueryServices)} is null.");
  173. if (hostPlayModeParameters.DeliveryQueryServices == null)
  174. throw new Exception($"{nameof(IDeliveryQueryServices)} is null.");
  175. if (hostPlayModeParameters.RemoteServices == null)
  176. throw new Exception($"{nameof(IRemoteServices)} is null.");
  177. }
  178. // 鉴定运行模式
  179. if (parameters is EditorSimulateModeParameters)
  180. _playMode = EPlayMode.EditorSimulateMode;
  181. else if (parameters is OfflinePlayModeParameters)
  182. _playMode = EPlayMode.OfflinePlayMode;
  183. else if (parameters is HostPlayModeParameters)
  184. _playMode = EPlayMode.HostPlayMode;
  185. else if (parameters is WebPlayModeParameters)
  186. _playMode = EPlayMode.WebPlayMode;
  187. else
  188. throw new NotImplementedException();
  189. // 检测运行时平台
  190. if (_playMode != EPlayMode.EditorSimulateMode)
  191. {
  192. #if UNITY_WEBGL
  193. if (_playMode != EPlayMode.WebPlayMode)
  194. {
  195. throw new Exception($"{_playMode} can not support WebGL plateform ! Please use {nameof(EPlayMode.WebPlayMode)}");
  196. }
  197. #else
  198. if (_playMode == EPlayMode.WebPlayMode)
  199. {
  200. throw new Exception($"{nameof(EPlayMode.WebPlayMode)} only support WebGL plateform !");
  201. }
  202. #endif
  203. }
  204. // 检测参数范围
  205. if (parameters.LoadingMaxTimeSlice < 10)
  206. {
  207. parameters.LoadingMaxTimeSlice = 10;
  208. YooLogger.Warning($"{nameof(parameters.LoadingMaxTimeSlice)} minimum value is 10 milliseconds.");
  209. }
  210. if (parameters.DownloadFailedTryAgain < 1)
  211. {
  212. parameters.DownloadFailedTryAgain = 1;
  213. YooLogger.Warning($"{nameof(parameters.DownloadFailedTryAgain)} minimum value is 1");
  214. }
  215. }
  216. private void InitializeOperation_Completed(AsyncOperationBase op)
  217. {
  218. _initializeStatus = op.Status;
  219. _initializeError = op.Error;
  220. }
  221. /// <summary>
  222. /// 向网络端请求最新的资源版本
  223. /// </summary>
  224. /// <param name="appendTimeTicks">在URL末尾添加时间戳</param>
  225. /// <param name="timeout">超时时间(默认值:60秒)</param>
  226. public UpdatePackageVersionOperation UpdatePackageVersionAsync(bool appendTimeTicks = true, int timeout = 60)
  227. {
  228. DebugCheckInitialize(false);
  229. return _playModeServices.UpdatePackageVersionAsync(appendTimeTicks, timeout);
  230. }
  231. /// <summary>
  232. /// 向网络端请求并更新清单
  233. /// </summary>
  234. /// <param name="packageVersion">更新的包裹版本</param>
  235. /// <param name="autoSaveVersion">更新成功后自动保存版本号,作为下次初始化的版本。</param>
  236. /// <param name="timeout">超时时间(默认值:60秒)</param>
  237. public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion = true, int timeout = 60)
  238. {
  239. DebugCheckInitialize(false);
  240. DebugCheckUpdateManifest();
  241. return _playModeServices.UpdatePackageManifestAsync(packageVersion, autoSaveVersion, timeout);
  242. }
  243. /// <summary>
  244. /// 预下载指定版本的包裹资源
  245. /// </summary>
  246. /// <param name="packageVersion">下载的包裹版本</param>
  247. /// <param name="timeout">超时时间(默认值:60秒)</param>
  248. public PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout = 60)
  249. {
  250. DebugCheckInitialize(false);
  251. return _playModeServices.PreDownloadContentAsync(packageVersion, timeout);
  252. }
  253. /// <summary>
  254. /// 清理包裹未使用的缓存文件
  255. /// </summary>
  256. public ClearUnusedCacheFilesOperation ClearUnusedCacheFilesAsync()
  257. {
  258. DebugCheckInitialize();
  259. var operation = new ClearUnusedCacheFilesOperation(this);
  260. OperationSystem.StartOperation(operation);
  261. return operation;
  262. }
  263. /// <summary>
  264. /// 清理包裹本地所有的缓存文件
  265. /// </summary>
  266. public ClearAllCacheFilesOperation ClearAllCacheFilesAsync()
  267. {
  268. DebugCheckInitialize();
  269. var operation = new ClearAllCacheFilesOperation(this);
  270. OperationSystem.StartOperation(operation);
  271. return operation;
  272. }
  273. /// <summary>
  274. /// 获取本地包裹的版本信息
  275. /// </summary>
  276. public string GetPackageVersion()
  277. {
  278. DebugCheckInitialize();
  279. return _playModeServices.ActiveManifest.PackageVersion;
  280. }
  281. /// <summary>
  282. /// 资源回收(卸载引用计数为零的资源)
  283. /// </summary>
  284. public void UnloadUnusedAssets()
  285. {
  286. DebugCheckInitialize();
  287. _assetSystemImpl.Update();
  288. _assetSystemImpl.UnloadUnusedAssets();
  289. }
  290. /// <summary>
  291. /// 强制回收所有资源
  292. /// </summary>
  293. public void ForceUnloadAllAssets()
  294. {
  295. DebugCheckInitialize();
  296. _assetSystemImpl.ForceUnloadAllAssets();
  297. }
  298. #region 沙盒相关
  299. /// <summary>
  300. /// 获取包裹的内置文件根路径
  301. /// </summary>
  302. public string GetPackageBuildinRootDirectory()
  303. {
  304. DebugCheckInitialize();
  305. var persistent = PersistentTools.GetPersistent(PackageName);
  306. return persistent.BuildinRoot;
  307. }
  308. /// <summary>
  309. /// 获取包裹的沙盒文件根路径
  310. /// </summary>
  311. public string GetPackageSandboxRootDirectory()
  312. {
  313. DebugCheckInitialize();
  314. var persistent = PersistentTools.GetPersistent(PackageName);
  315. return persistent.SandboxRoot;
  316. }
  317. /// <summary>
  318. /// 清空包裹的沙盒目录
  319. /// </summary>
  320. public void ClearPackageSandbox()
  321. {
  322. DebugCheckInitialize();
  323. var persistent = PersistentTools.GetPersistent(PackageName);
  324. persistent.DeleteSandboxPackageFolder();
  325. }
  326. #endregion
  327. #region 资源信息
  328. /// <summary>
  329. /// 是否需要从远端更新下载
  330. /// </summary>
  331. /// <param name="location">资源的定位地址</param>
  332. public bool IsNeedDownloadFromRemote(string location)
  333. {
  334. DebugCheckInitialize();
  335. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
  336. if (assetInfo.IsInvalid)
  337. {
  338. YooLogger.Warning(assetInfo.Error);
  339. return false;
  340. }
  341. BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
  342. if (bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
  343. return true;
  344. else
  345. return false;
  346. }
  347. /// <summary>
  348. /// 是否需要从远端更新下载
  349. /// </summary>
  350. /// <param name="location">资源的定位地址</param>
  351. public bool IsNeedDownloadFromRemote(AssetInfo assetInfo)
  352. {
  353. DebugCheckInitialize();
  354. if (assetInfo.IsInvalid)
  355. {
  356. YooLogger.Warning(assetInfo.Error);
  357. return false;
  358. }
  359. BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
  360. if (bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
  361. return true;
  362. else
  363. return false;
  364. }
  365. /// <summary>
  366. /// 获取资源信息列表
  367. /// </summary>
  368. /// <param name="tag">资源标签</param>
  369. public AssetInfo[] GetAssetInfos(string tag)
  370. {
  371. DebugCheckInitialize();
  372. string[] tags = new string[] { tag };
  373. return _playModeServices.ActiveManifest.GetAssetsInfoByTags(tags);
  374. }
  375. /// <summary>
  376. /// 获取资源信息列表
  377. /// </summary>
  378. /// <param name="tags">资源标签列表</param>
  379. public AssetInfo[] GetAssetInfos(string[] tags)
  380. {
  381. DebugCheckInitialize();
  382. return _playModeServices.ActiveManifest.GetAssetsInfoByTags(tags);
  383. }
  384. /// <summary>
  385. /// 获取资源信息
  386. /// </summary>
  387. /// <param name="location">资源的定位地址</param>
  388. public AssetInfo GetAssetInfo(string location)
  389. {
  390. DebugCheckInitialize();
  391. return ConvertLocationToAssetInfo(location, null);
  392. }
  393. /// <summary>
  394. /// 获取资源信息
  395. /// </summary>
  396. /// <param name="assetGUID">资源GUID</param>
  397. public AssetInfo GetAssetInfoByGUID(string assetGUID)
  398. {
  399. DebugCheckInitialize();
  400. return ConvertAssetGUIDToAssetInfo(assetGUID, null);
  401. }
  402. /// <summary>
  403. /// 检查资源定位地址是否有效
  404. /// </summary>
  405. /// <param name="location">资源的定位地址</param>
  406. public bool CheckLocationValid(string location)
  407. {
  408. DebugCheckInitialize();
  409. string assetPath = _playModeServices.ActiveManifest.TryMappingToAssetPath(location);
  410. return string.IsNullOrEmpty(assetPath) == false;
  411. }
  412. #endregion
  413. #region 原生文件
  414. /// <summary>
  415. /// 同步加载原生文件
  416. /// </summary>
  417. /// <param name="assetInfo">资源信息</param>
  418. public RawFileOperationHandle LoadRawFileSync(AssetInfo assetInfo)
  419. {
  420. DebugCheckInitialize();
  421. return LoadRawFileInternal(assetInfo, true);
  422. }
  423. /// <summary>
  424. /// 同步加载原生文件
  425. /// </summary>
  426. /// <param name="location">资源的定位地址</param>
  427. public RawFileOperationHandle LoadRawFileSync(string location)
  428. {
  429. DebugCheckInitialize();
  430. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
  431. return LoadRawFileInternal(assetInfo, true);
  432. }
  433. /// <summary>
  434. /// 异步加载原生文件
  435. /// </summary>
  436. /// <param name="assetInfo">资源信息</param>
  437. public RawFileOperationHandle LoadRawFileAsync(AssetInfo assetInfo)
  438. {
  439. DebugCheckInitialize();
  440. return LoadRawFileInternal(assetInfo, false);
  441. }
  442. /// <summary>
  443. /// 异步加载原生文件
  444. /// </summary>
  445. /// <param name="location">资源的定位地址</param>
  446. public RawFileOperationHandle LoadRawFileAsync(string location)
  447. {
  448. DebugCheckInitialize();
  449. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
  450. return LoadRawFileInternal(assetInfo, false);
  451. }
  452. private RawFileOperationHandle LoadRawFileInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
  453. {
  454. #if UNITY_EDITOR
  455. if (assetInfo.IsInvalid == false)
  456. {
  457. BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
  458. if (bundleInfo.Bundle.IsRawFile == false)
  459. throw new Exception($"Cannot load asset bundle file using {nameof(LoadRawFileAsync)} method !");
  460. }
  461. #endif
  462. var handle = _assetSystemImpl.LoadRawFileAsync(assetInfo);
  463. if (waitForAsyncComplete)
  464. handle.WaitForAsyncComplete();
  465. return handle;
  466. }
  467. #endregion
  468. #region 场景加载
  469. /// <summary>
  470. /// 异步加载场景
  471. /// </summary>
  472. /// <param name="location">场景的定位地址</param>
  473. /// <param name="sceneMode">场景加载模式</param>
  474. /// <param name="suspendLoad">场景加载到90%自动挂起</param>
  475. /// <param name="priority">优先级</param>
  476. public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100)
  477. {
  478. DebugCheckInitialize();
  479. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
  480. var handle = _assetSystemImpl.LoadSceneAsync(assetInfo, sceneMode, suspendLoad, priority);
  481. return handle;
  482. }
  483. /// <summary>
  484. /// 异步加载场景
  485. /// </summary>
  486. /// <param name="assetInfo">场景的资源信息</param>
  487. /// <param name="sceneMode">场景加载模式</param>
  488. /// <param name="suspendLoad">场景加载到90%自动挂起</param>
  489. /// <param name="priority">优先级</param>
  490. public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100)
  491. {
  492. DebugCheckInitialize();
  493. var handle = _assetSystemImpl.LoadSceneAsync(assetInfo, sceneMode, suspendLoad, priority);
  494. return handle;
  495. }
  496. #endregion
  497. #region 资源加载
  498. /// <summary>
  499. /// 同步加载资源对象
  500. /// </summary>
  501. /// <param name="assetInfo">资源信息</param>
  502. public AssetOperationHandle LoadAssetSync(AssetInfo assetInfo)
  503. {
  504. DebugCheckInitialize();
  505. return LoadAssetInternal(assetInfo, true);
  506. }
  507. /// <summary>
  508. /// 同步加载资源对象
  509. /// </summary>
  510. /// <typeparam name="TObject">资源类型</typeparam>
  511. /// <param name="location">资源的定位地址</param>
  512. public AssetOperationHandle LoadAssetSync<TObject>(string location) where TObject : UnityEngine.Object
  513. {
  514. DebugCheckInitialize();
  515. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
  516. return LoadAssetInternal(assetInfo, true);
  517. }
  518. /// <summary>
  519. /// 同步加载资源对象
  520. /// </summary>
  521. /// <param name="location">资源的定位地址</param>
  522. /// <param name="type">资源类型</param>
  523. public AssetOperationHandle LoadAssetSync(string location, System.Type type)
  524. {
  525. DebugCheckInitialize();
  526. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  527. return LoadAssetInternal(assetInfo, true);
  528. }
  529. /// <summary>
  530. /// 同步加载资源对象
  531. /// </summary>
  532. /// <param name="location">资源的定位地址</param>
  533. public AssetOperationHandle LoadAssetSync(string location)
  534. {
  535. DebugCheckInitialize();
  536. Type type = typeof(UnityEngine.Object);
  537. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  538. return LoadAssetInternal(assetInfo, true);
  539. }
  540. /// <summary>
  541. /// 异步加载资源对象
  542. /// </summary>
  543. /// <param name="assetInfo">资源信息</param>
  544. public AssetOperationHandle LoadAssetAsync(AssetInfo assetInfo)
  545. {
  546. DebugCheckInitialize();
  547. return LoadAssetInternal(assetInfo, false);
  548. }
  549. /// <summary>
  550. /// 异步加载资源对象
  551. /// </summary>
  552. /// <typeparam name="TObject">资源类型</typeparam>
  553. /// <param name="location">资源的定位地址</param>
  554. public AssetOperationHandle LoadAssetAsync<TObject>(string location) where TObject : UnityEngine.Object
  555. {
  556. DebugCheckInitialize();
  557. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
  558. return LoadAssetInternal(assetInfo, false);
  559. }
  560. /// <summary>
  561. /// 异步加载资源对象
  562. /// </summary>
  563. /// <param name="location">资源的定位地址</param>
  564. /// <param name="type">资源类型</param>
  565. public AssetOperationHandle LoadAssetAsync(string location, System.Type type)
  566. {
  567. DebugCheckInitialize();
  568. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  569. return LoadAssetInternal(assetInfo, false);
  570. }
  571. /// <summary>
  572. /// 异步加载资源对象
  573. /// </summary>
  574. /// <param name="location">资源的定位地址</param>
  575. public AssetOperationHandle LoadAssetAsync(string location)
  576. {
  577. DebugCheckInitialize();
  578. Type type = typeof(UnityEngine.Object);
  579. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  580. return LoadAssetInternal(assetInfo, false);
  581. }
  582. private AssetOperationHandle LoadAssetInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
  583. {
  584. #if UNITY_EDITOR
  585. if (assetInfo.IsInvalid == false)
  586. {
  587. BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
  588. if (bundleInfo.Bundle.IsRawFile)
  589. throw new Exception($"Cannot load raw file using {nameof(LoadAssetAsync)} method !");
  590. }
  591. #endif
  592. var handle = _assetSystemImpl.LoadAssetAsync(assetInfo);
  593. if (waitForAsyncComplete)
  594. handle.WaitForAsyncComplete();
  595. return handle;
  596. }
  597. #endregion
  598. #region 资源加载
  599. /// <summary>
  600. /// 同步加载子资源对象
  601. /// </summary>
  602. /// <param name="assetInfo">资源信息</param>
  603. public SubAssetsOperationHandle LoadSubAssetsSync(AssetInfo assetInfo)
  604. {
  605. DebugCheckInitialize();
  606. return LoadSubAssetsInternal(assetInfo, true);
  607. }
  608. /// <summary>
  609. /// 同步加载子资源对象
  610. /// </summary>
  611. /// <typeparam name="TObject">资源类型</typeparam>
  612. /// <param name="location">资源的定位地址</param>
  613. public SubAssetsOperationHandle LoadSubAssetsSync<TObject>(string location) where TObject : UnityEngine.Object
  614. {
  615. DebugCheckInitialize();
  616. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
  617. return LoadSubAssetsInternal(assetInfo, true);
  618. }
  619. /// <summary>
  620. /// 同步加载子资源对象
  621. /// </summary>
  622. /// <param name="location">资源的定位地址</param>
  623. /// <param name="type">子对象类型</param>
  624. public SubAssetsOperationHandle LoadSubAssetsSync(string location, System.Type type)
  625. {
  626. DebugCheckInitialize();
  627. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  628. return LoadSubAssetsInternal(assetInfo, true);
  629. }
  630. /// <summary>
  631. /// 同步加载子资源对象
  632. /// </summary>
  633. /// <param name="location">资源的定位地址</param>
  634. public SubAssetsOperationHandle LoadSubAssetsSync(string location)
  635. {
  636. DebugCheckInitialize();
  637. Type type = typeof(UnityEngine.Object);
  638. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  639. return LoadSubAssetsInternal(assetInfo, true);
  640. }
  641. /// <summary>
  642. /// 异步加载子资源对象
  643. /// </summary>
  644. /// <param name="assetInfo">资源信息</param>
  645. public SubAssetsOperationHandle LoadSubAssetsAsync(AssetInfo assetInfo)
  646. {
  647. DebugCheckInitialize();
  648. return LoadSubAssetsInternal(assetInfo, false);
  649. }
  650. /// <summary>
  651. /// 异步加载子资源对象
  652. /// </summary>
  653. /// <typeparam name="TObject">资源类型</typeparam>
  654. /// <param name="location">资源的定位地址</param>
  655. public SubAssetsOperationHandle LoadSubAssetsAsync<TObject>(string location) where TObject : UnityEngine.Object
  656. {
  657. DebugCheckInitialize();
  658. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
  659. return LoadSubAssetsInternal(assetInfo, false);
  660. }
  661. /// <summary>
  662. /// 异步加载子资源对象
  663. /// </summary>
  664. /// <param name="location">资源的定位地址</param>
  665. /// <param name="type">子对象类型</param>
  666. public SubAssetsOperationHandle LoadSubAssetsAsync(string location, System.Type type)
  667. {
  668. DebugCheckInitialize();
  669. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  670. return LoadSubAssetsInternal(assetInfo, false);
  671. }
  672. /// <summary>
  673. /// 异步加载子资源对象
  674. /// </summary>
  675. /// <param name="location">资源的定位地址</param>
  676. public SubAssetsOperationHandle LoadSubAssetsAsync(string location)
  677. {
  678. DebugCheckInitialize();
  679. Type type = typeof(UnityEngine.Object);
  680. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  681. return LoadSubAssetsInternal(assetInfo, false);
  682. }
  683. private SubAssetsOperationHandle LoadSubAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
  684. {
  685. #if UNITY_EDITOR
  686. if (assetInfo.IsInvalid == false)
  687. {
  688. BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
  689. if (bundleInfo.Bundle.IsRawFile)
  690. throw new Exception($"Cannot load raw file using {nameof(LoadSubAssetsAsync)} method !");
  691. }
  692. #endif
  693. var handle = _assetSystemImpl.LoadSubAssetsAsync(assetInfo);
  694. if (waitForAsyncComplete)
  695. handle.WaitForAsyncComplete();
  696. return handle;
  697. }
  698. #endregion
  699. #region 资源加载
  700. /// <summary>
  701. /// 同步加载资源包内所有资源对象
  702. /// </summary>
  703. /// <param name="assetInfo">资源信息</param>
  704. public AllAssetsOperationHandle LoadAllAssetsSync(AssetInfo assetInfo)
  705. {
  706. DebugCheckInitialize();
  707. return LoadAllAssetsInternal(assetInfo, true);
  708. }
  709. /// <summary>
  710. /// 同步加载资源包内所有资源对象
  711. /// </summary>
  712. /// <typeparam name="TObject">资源类型</typeparam>
  713. /// <param name="location">资源的定位地址</param>
  714. public AllAssetsOperationHandle LoadAllAssetsSync<TObject>(string location) where TObject : UnityEngine.Object
  715. {
  716. DebugCheckInitialize();
  717. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
  718. return LoadAllAssetsInternal(assetInfo, true);
  719. }
  720. /// <summary>
  721. /// 同步加载资源包内所有资源对象
  722. /// </summary>
  723. /// <param name="location">资源的定位地址</param>
  724. /// <param name="type">子对象类型</param>
  725. public AllAssetsOperationHandle LoadAllAssetsSync(string location, System.Type type)
  726. {
  727. DebugCheckInitialize();
  728. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  729. return LoadAllAssetsInternal(assetInfo, true);
  730. }
  731. /// <summary>
  732. /// 同步加载资源包内所有资源对象
  733. /// </summary>
  734. /// <param name="location">资源的定位地址</param>
  735. public AllAssetsOperationHandle LoadAllAssetsSync(string location)
  736. {
  737. DebugCheckInitialize();
  738. Type type = typeof(UnityEngine.Object);
  739. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  740. return LoadAllAssetsInternal(assetInfo, true);
  741. }
  742. /// <summary>
  743. /// 异步加载资源包内所有资源对象
  744. /// </summary>
  745. /// <param name="assetInfo">资源信息</param>
  746. public AllAssetsOperationHandle LoadAllAssetsAsync(AssetInfo assetInfo)
  747. {
  748. DebugCheckInitialize();
  749. return LoadAllAssetsInternal(assetInfo, false);
  750. }
  751. /// <summary>
  752. /// 异步加载资源包内所有资源对象
  753. /// </summary>
  754. /// <typeparam name="TObject">资源类型</typeparam>
  755. /// <param name="location">资源的定位地址</param>
  756. public AllAssetsOperationHandle LoadAllAssetsAsync<TObject>(string location) where TObject : UnityEngine.Object
  757. {
  758. DebugCheckInitialize();
  759. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
  760. return LoadAllAssetsInternal(assetInfo, false);
  761. }
  762. /// <summary>
  763. /// 异步加载资源包内所有资源对象
  764. /// </summary>
  765. /// <param name="location">资源的定位地址</param>
  766. /// <param name="type">子对象类型</param>
  767. public AllAssetsOperationHandle LoadAllAssetsAsync(string location, System.Type type)
  768. {
  769. DebugCheckInitialize();
  770. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  771. return LoadAllAssetsInternal(assetInfo, false);
  772. }
  773. /// <summary>
  774. /// 异步加载资源包内所有资源对象
  775. /// </summary>
  776. /// <param name="location">资源的定位地址</param>
  777. public AllAssetsOperationHandle LoadAllAssetsAsync(string location)
  778. {
  779. DebugCheckInitialize();
  780. Type type = typeof(UnityEngine.Object);
  781. AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
  782. return LoadAllAssetsInternal(assetInfo, false);
  783. }
  784. private AllAssetsOperationHandle LoadAllAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
  785. {
  786. #if UNITY_EDITOR
  787. if (assetInfo.IsInvalid == false)
  788. {
  789. BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
  790. if (bundleInfo.Bundle.IsRawFile)
  791. throw new Exception($"Cannot load raw file using {nameof(LoadAllAssetsAsync)} method !");
  792. }
  793. #endif
  794. var handle = _assetSystemImpl.LoadAllAssetsAsync(assetInfo);
  795. if (waitForAsyncComplete)
  796. handle.WaitForAsyncComplete();
  797. return handle;
  798. }
  799. #endregion
  800. #region 资源下载
  801. /// <summary>
  802. /// 创建资源下载器,用于下载当前资源版本所有的资源包文件
  803. /// </summary>
  804. /// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
  805. /// <param name="failedTryAgain">下载失败的重试次数</param>
  806. /// <param name="timeout">超时时间</param>
  807. public ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
  808. {
  809. DebugCheckInitialize();
  810. return _playModeServices.CreateResourceDownloaderByAll(downloadingMaxNumber, failedTryAgain, timeout);
  811. }
  812. /// <summary>
  813. /// 创建资源下载器,用于下载指定的资源标签关联的资源包文件
  814. /// </summary>
  815. /// <param name="tag">资源标签</param>
  816. /// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
  817. /// <param name="failedTryAgain">下载失败的重试次数</param>
  818. /// <param name="timeout">超时时间</param>
  819. public ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
  820. {
  821. DebugCheckInitialize();
  822. return _playModeServices.CreateResourceDownloaderByTags(new string[] { tag }, downloadingMaxNumber, failedTryAgain, timeout);
  823. }
  824. /// <summary>
  825. /// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件
  826. /// </summary>
  827. /// <param name="tags">资源标签列表</param>
  828. /// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
  829. /// <param name="failedTryAgain">下载失败的重试次数</param>
  830. /// <param name="timeout">超时时间</param>
  831. public ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
  832. {
  833. DebugCheckInitialize();
  834. return _playModeServices.CreateResourceDownloaderByTags(tags, downloadingMaxNumber, failedTryAgain, timeout);
  835. }
  836. /// <summary>
  837. /// 创建资源下载器,用于下载指定的资源依赖的资源包文件
  838. /// </summary>
  839. /// <param name="location">资源的定位地址</param>
  840. /// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
  841. /// <param name="failedTryAgain">下载失败的重试次数</param>
  842. /// <param name="timeout">超时时间</param>
  843. public ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
  844. {
  845. DebugCheckInitialize();
  846. var assetInfo = ConvertLocationToAssetInfo(location, null);
  847. AssetInfo[] assetInfos = new AssetInfo[] { assetInfo };
  848. return _playModeServices.CreateResourceDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout);
  849. }
  850. /// <summary>
  851. /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件
  852. /// </summary>
  853. /// <param name="locations">资源的定位地址列表</param>
  854. /// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
  855. /// <param name="failedTryAgain">下载失败的重试次数</param>
  856. /// <param name="timeout">超时时间</param>
  857. public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
  858. {
  859. DebugCheckInitialize();
  860. List<AssetInfo> assetInfos = new List<AssetInfo>(locations.Length);
  861. foreach (var location in locations)
  862. {
  863. var assetInfo = ConvertLocationToAssetInfo(location, null);
  864. assetInfos.Add(assetInfo);
  865. }
  866. return _playModeServices.CreateResourceDownloaderByPaths(assetInfos.ToArray(), downloadingMaxNumber, failedTryAgain, timeout);
  867. }
  868. /// <summary>
  869. /// 创建资源下载器,用于下载指定的资源依赖的资源包文件
  870. /// </summary>
  871. /// <param name="assetInfo">资源信息</param>
  872. /// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
  873. /// <param name="failedTryAgain">下载失败的重试次数</param>
  874. /// <param name="timeout">超时时间</param>
  875. public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
  876. {
  877. DebugCheckInitialize();
  878. AssetInfo[] assetInfos = new AssetInfo[] { assetInfo };
  879. return _playModeServices.CreateResourceDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout);
  880. }
  881. /// <summary>
  882. /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件
  883. /// </summary>
  884. /// <param name="assetInfos">资源信息列表</param>
  885. /// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
  886. /// <param name="failedTryAgain">下载失败的重试次数</param>
  887. /// <param name="timeout">超时时间</param>
  888. public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
  889. {
  890. DebugCheckInitialize();
  891. return _playModeServices.CreateResourceDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout);
  892. }
  893. #endregion
  894. #region 资源解压
  895. /// <summary>
  896. /// 创建内置资源解压器
  897. /// </summary>
  898. /// <param name="tag">资源标签</param>
  899. /// <param name="unpackingMaxNumber">同时解压的最大文件数</param>
  900. /// <param name="failedTryAgain">解压失败的重试次数</param>
  901. public ResourceUnpackerOperation CreateResourceUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain)
  902. {
  903. DebugCheckInitialize();
  904. return _playModeServices.CreateResourceUnpackerByTags(new string[] { tag }, unpackingMaxNumber, failedTryAgain, int.MaxValue);
  905. }
  906. /// <summary>
  907. /// 创建内置资源解压器
  908. /// </summary>
  909. /// <param name="tags">资源标签列表</param>
  910. /// <param name="unpackingMaxNumber">同时解压的最大文件数</param>
  911. /// <param name="failedTryAgain">解压失败的重试次数</param>
  912. public ResourceUnpackerOperation CreateResourceUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain)
  913. {
  914. DebugCheckInitialize();
  915. return _playModeServices.CreateResourceUnpackerByTags(tags, unpackingMaxNumber, failedTryAgain, int.MaxValue);
  916. }
  917. /// <summary>
  918. /// 创建内置资源解压器
  919. /// </summary>
  920. /// <param name="unpackingMaxNumber">同时解压的最大文件数</param>
  921. /// <param name="failedTryAgain">解压失败的重试次数</param>
  922. public ResourceUnpackerOperation CreateResourceUnpacker(int unpackingMaxNumber, int failedTryAgain)
  923. {
  924. DebugCheckInitialize();
  925. return _playModeServices.CreateResourceUnpackerByAll(unpackingMaxNumber, failedTryAgain, int.MaxValue);
  926. }
  927. #endregion
  928. #region 内部方法
  929. /// <summary>
  930. /// 是否包含资源文件
  931. /// </summary>
  932. internal bool IsIncludeBundleFile(string cacheGUID)
  933. {
  934. // NOTE : 编辑器模拟模式下始终返回TRUE
  935. if (_playMode == EPlayMode.EditorSimulateMode)
  936. return true;
  937. return _playModeServices.ActiveManifest.IsIncludeBundleFile(cacheGUID);
  938. }
  939. private AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
  940. {
  941. return _playModeServices.ActiveManifest.ConvertLocationToAssetInfo(location, assetType);
  942. }
  943. private AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType)
  944. {
  945. return _playModeServices.ActiveManifest.ConvertAssetGUIDToAssetInfo(assetGUID, assetType);
  946. }
  947. #endregion
  948. #region 调试方法
  949. [Conditional("DEBUG")]
  950. private void DebugCheckInitialize(bool checkActiveManifest = true)
  951. {
  952. if (_initializeStatus == EOperationStatus.None)
  953. throw new Exception("Package initialize not completed !");
  954. else if (_initializeStatus == EOperationStatus.Failed)
  955. throw new Exception($"Package initialize failed ! {_initializeError}");
  956. if (checkActiveManifest)
  957. {
  958. if (_playModeServices.ActiveManifest == null)
  959. throw new Exception("Not found active manifest !");
  960. }
  961. }
  962. [Conditional("DEBUG")]
  963. private void DebugCheckUpdateManifest()
  964. {
  965. var loadedBundleInfos = _assetSystemImpl.GetLoadedBundleInfos();
  966. if (loadedBundleInfos.Count > 0)
  967. {
  968. YooLogger.Warning($"Found loaded bundle before update manifest ! Recommended to call the {nameof(ForceUnloadAllAssets)} method to release loaded bundle !");
  969. }
  970. }
  971. #endregion
  972. #region 调试信息
  973. internal DebugPackageData GetDebugPackageData()
  974. {
  975. DebugPackageData data = new DebugPackageData();
  976. data.PackageName = PackageName;
  977. data.ProviderInfos = _assetSystemImpl.GetDebugReportInfos();
  978. return data;
  979. }
  980. #endregion
  981. }
  982. }