AssetManager.static.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using XGame.Framework.Asyncs;
  2. using XGame.Framework.i18n;
  3. using XGame.Framework.Quality;
  4. #if UNITY_EDITOR
  5. using System.Linq;
  6. #endif
  7. namespace XGame.Framework.Asset
  8. {
  9. public sealed partial class AssetManager
  10. {
  11. private static IAssetManager _assetMgr;
  12. private static IAssetManager Instance => _assetMgr;
  13. public static IAsync Init()
  14. {
  15. var loaderAsync = new LoaderBuildAsync();
  16. loaderAsync.Start();
  17. loaderAsync.On(_ =>
  18. {
  19. var loader = loaderAsync.Result;
  20. if (loader != null)
  21. _assetMgr = new AssetManager(loader);
  22. Log.Debug($"LoaderBuildAsync completed. loader:{_assetMgr != null}");
  23. });
  24. return loaderAsync;
  25. }
  26. public static void ChangedLanguage(LanguageType langFlag)
  27. {
  28. if (_assetMgr != null && _assetMgr is AssetManager manager)
  29. {
  30. manager.SetLangueType(langFlag);
  31. }
  32. else
  33. {
  34. AssetsLog.Error($"IAssetManager has dispose. But ChangedLanguage Event callback.");
  35. }
  36. }
  37. public static void ChangeQualityLevel(XQualityLevel quality)
  38. {
  39. if (_assetMgr != null && _assetMgr is AssetManager manager)
  40. {
  41. manager.SetQuality(quality);
  42. }
  43. else
  44. {
  45. AssetsLog.Error($"IAssetManager had dispose. But ChangeQualityLevel Event callback.");
  46. }
  47. }
  48. /// <summary>
  49. /// 转换AddressableName
  50. /// 会根据游戏当前语言、品质等级返回对应的AddressableName
  51. /// </summary>
  52. /// <param name="addressableName"></param>
  53. /// <returns></returns>
  54. public static string ConvertAddressableName(string addressableName)
  55. {
  56. if (_assetMgr != null)
  57. {
  58. return _assetMgr.ConvertAddressableName(addressableName);
  59. }
  60. return addressableName;
  61. }
  62. /// <summary>
  63. /// 同步加载接口
  64. /// 非必要不要使用
  65. /// webgl、微信小游戏不能使用
  66. /// 使用该接口加载的资源严禁使用Object.Destroy销毁,只能使用Recycle(obj)方法回收
  67. /// </summary>
  68. /// <typeparam name="TResult">返回值类型</typeparam>
  69. /// <param name="addressableName">可寻址资源名字</param>
  70. /// <returns>返回泛型对象</returns>
  71. public static TResult LoadSync<TResult>(string addressableName)
  72. {
  73. #if UNITY_EDITOR
  74. if (TryLoadSyncForEditor(addressableName, out TResult result))
  75. {
  76. return result;
  77. }
  78. #endif
  79. return Instance.LoadSync<TResult>(addressableName);
  80. }
  81. /// <summary>
  82. /// 异步加载接口
  83. /// 使用该接口加载的资源严禁使用Object.Destroy销毁,只能使用Recycle(obj)方法回收
  84. /// </summary>
  85. /// <typeparam name="TResult">返回对象类型</typeparam>
  86. /// <param name="addressableName">可寻址资源名字</param>
  87. /// <returns>返回异步回调</returns>
  88. public static IAssetLoadAsync<TResult> LoadAsync<TResult>(string addressableName)
  89. {
  90. #if UNITY_EDITOR
  91. Assert.IsTrue(UnityEngine.Application.isPlaying, "非运行时加载资源请使用 AddressableHelper.LoadAssetByAddressableName()");
  92. Assert.IsTrue(_assetMgr != null, $"AssetManager没有实例化. Thread:{System.Threading.Thread.CurrentThread.ManagedThreadId}");
  93. #endif
  94. return Instance.LoadAsync<TResult>(addressableName);
  95. }
  96. /// <summary>
  97. /// 加载Scene的AssetBundle到内存
  98. /// </summary>
  99. /// <param name="bundleName"></param>
  100. public static IAsync LoadSceneBundle(string sceneName)
  101. {
  102. return Instance.LoadSceneBundle(sceneName);
  103. }
  104. public static void UnLoadSceneBundle(string sceneName)
  105. {
  106. Instance.UnLoadSceneBundle(sceneName);
  107. }
  108. /// <summary>
  109. /// 回收资源
  110. /// </summary>
  111. /// <param name="obj"></param>
  112. public static void Recycle(object obj)
  113. {
  114. #if UNITY_EDITOR
  115. if (!UnityEngine.Application.isPlaying)
  116. {
  117. return;
  118. }
  119. #endif
  120. Instance.Recycle(obj);
  121. }
  122. /// <summary>
  123. /// 停止指定的异步加载
  124. /// </summary>
  125. /// <typeparam name="TResult"></typeparam>
  126. /// <param name="async"></param>
  127. public static void StopAsync<TResult>(IAssetLoadAsync<TResult> async)
  128. {
  129. Instance.StopAsync(async);
  130. }
  131. /// <summary>
  132. /// 卸载当前未使用的资源
  133. /// </summary>
  134. public static void UnloadUnusedAssets()
  135. {
  136. Instance.UnloadUnusedAssets();
  137. }
  138. /// <summary>
  139. /// 销毁manager
  140. /// </summary>
  141. /// <returns></returns>
  142. public static IAsync Dispose()
  143. {
  144. Log.Debug($"AssetManager Dispose. {_assetMgr != null}");
  145. if (_assetMgr != null)
  146. {
  147. var async = _assetMgr.Dispose();
  148. _assetMgr = null;
  149. //async.On((aAsync => { _assetMgr = null; }));
  150. return async;
  151. }
  152. return null;
  153. }
  154. /// <summary>
  155. /// 销毁旧的,重新初始化manager
  156. /// </summary>
  157. /// <returns></returns>
  158. public static IAsync ReStart()
  159. {
  160. var asyncGroup = new AsyncGroup();
  161. var loaderAsync = new LoaderBuildAsync();
  162. if (_assetMgr != null)
  163. {
  164. var disposeAsync = _assetMgr.Dispose();
  165. disposeAsync.Join(asyncGroup);
  166. disposeAsync.On(_ =>
  167. {
  168. _assetMgr = null;
  169. loaderAsync.Start();
  170. });
  171. }
  172. else
  173. {
  174. loaderAsync.Start();
  175. }
  176. loaderAsync.Join(asyncGroup);
  177. loaderAsync.On(_ =>
  178. {
  179. var loader = loaderAsync.Result;
  180. if (loader != null)
  181. _assetMgr = new AssetManager(loader);
  182. });
  183. asyncGroup.End();
  184. return asyncGroup;
  185. }
  186. /// <summary>
  187. /// 设置资源的预加载标记
  188. /// </summary>
  189. /// <param name="addressableName"></param>
  190. /// <param name="isPreload"></param>
  191. public static void SetPreloadTag(string addressableName, bool isPreload)
  192. {
  193. if (_assetMgr is IAssetCacheHandle handle)
  194. {
  195. handle.SetPreloadTag(addressableName, isPreload);
  196. }
  197. }
  198. #if UNITY_EDITOR
  199. private static IAssetLoadHandler _loadHandler;
  200. private static IAssetLoadHandler LoaderHandler
  201. {
  202. get
  203. {
  204. if (_loadHandler == null)
  205. {
  206. var hostEditorName = "Framework.Editor";
  207. var adapterType = typeof(IAssetLoadHandler);
  208. var handlerImplType = System.AppDomain.CurrentDomain.GetAssemblies()
  209. .First(assembly => assembly.GetName().Name.Equals(hostEditorName))
  210. .GetTypes().First(type => adapterType.IsAssignableFrom(type));
  211. if (handlerImplType != null)
  212. {
  213. _loadHandler = System.Activator.CreateInstance(handlerImplType) as IAssetLoadHandler;
  214. }
  215. else
  216. {
  217. UnityEngine.Debug.LogError("没有找到 IAssetLoaderHandler 的实现类。");
  218. }
  219. }
  220. return _loadHandler;
  221. }
  222. }
  223. private static bool TryLoadSyncForEditor<TResult>(string addressableName, out TResult result)
  224. {
  225. if (UnityEngine.Application.isPlaying == false)
  226. {
  227. if (LoaderHandler != null)
  228. {
  229. result = LoaderHandler.LoadSync<TResult>(addressableName);
  230. }
  231. else
  232. {
  233. result = default(TResult);
  234. }
  235. return true;
  236. }
  237. result = default;
  238. return false;
  239. }
  240. #endif
  241. }
  242. }