using XGame.Framework.Utils; using XGame.Framework.Asset.Addressable; using System; using UnityEngine; using XGame.Framework.Asyncs; using UnityEngine.Networking; namespace XGame.Framework.Asset { internal partial class LoaderBuildAsync : Async, IAsyncResultable { private LoaderType _loadType; private AssetBundle _mainbundle; private bool _isBundleEncrypt; public IAssetLoader Result { get; private set; } public LoaderBuildAsync() { #if UNITY_EDITOR var isSimluator = UnityEditor.EditorPrefs.GetBool(Define.SIMULATE_ASSETBUNDLE_EDITOR_KEY, true); _loadType = isSimluator ? LoaderType.AssetDatabase : LoaderType.AssetBundle; #else _loadType = LoaderType.AssetBundle; #endif } // private void InitMainbundle() // { // if (_loadType == LoaderType.AssetBundle) // { //#if UNITY_EDITOR // InitMainBundleEditor(); //#else // _isBundleEncrypt = true; // var bundlePath = FileUtils.GetAssetBundlePath(Define.MANIFEST_BUNDLE_FULLNAME); // _mainbundle = AssetBundle.LoadFromFile(bundlePath, 0, Define.MANIFEST_BUNDLE_OFFSET);//"kcmanifest.bundle" //#endif // } // } private IAddressableManifest LoadAddressableManifest() { if (_loadType == LoaderType.AssetDatabase) { #if UNITY_EDITOR return LoadAddressableManifestEditor(); #endif } else if (_loadType == LoaderType.AssetBundle) { var manifest = new CSharpAddressableManifest(); if (_mainbundle != null) { var builtInAssetSo = _mainbundle.LoadAsset(Define.BUILTIN_ASSET_MANIFEST); manifest.Init(builtInAssetSo); var productAssetSo = _mainbundle.LoadAsset(Define.PRODUCT_ASSET_MANIFEST); manifest.Init(productAssetSo); } return manifest; } return null; } private IAssetLoader CreateLoader(LoaderType loaderType, IAddressableManifest addressableManifest) { IAssetLoader loader = null; switch (loaderType) { case LoaderType.AssetDatabase: #if UNITY_EDITOR loader = new AssetDatabaseLoader(addressableManifest as IAddressableEditorHandler); #endif break; case LoaderType.AssetBundle: { var bundlesSo = _mainbundle?.LoadAsset(Define.ASSET_BUNDLE_MANIFEST) ?? null;//"KCAssetBundleManifest" var bundleManifest = new CSharpAssetBundleManifest(bundlesSo); var referencesSo = _mainbundle?.LoadAsset(Define.ASSET_REFERENCE_MANIFEST) ?? null; var referenceManifest = new CSharpAssetReferencesManifest(referencesSo); var sceneInfosSo = _mainbundle?.LoadAsset(Define.SCENE_BUNDLE_MANIFEST) ?? null; var sceneInfosManifest = new CSharpSceneInfosManifest(sceneInfosSo); loader = new AssetBundleLoader(bundleManifest, referenceManifest, sceneInfosManifest) { IsBundleEncrypt = _isBundleEncrypt }; } break; case LoaderType.Resources: loader = new ResourcesLoader(addressableManifest); break; case LoaderType.Binary: loader = new BinaryLoader(); break; } return loader; } private void Release() { _mainbundle?.Unload(true); _mainbundle = null; } private IAssetLoader Build() { var addressableManifest = LoadAddressableManifest(); var array = Enum.GetValues(typeof(LoaderType)); var loaders = new IAssetLoader[array.Length]; foreach (LoaderType enumVal in array) { if ((enumVal == LoaderType.AssetBundle && _loadType == LoaderType.AssetDatabase) || (enumVal == LoaderType.AssetDatabase && _loadType == LoaderType.AssetBundle)) {//创建Loader时AssetDatabase和AssetBundle二选一 continue; } loaders[(int)enumVal] = CreateLoader(enumVal, addressableManifest); } var adapter = new AssetLoader(_loadType, loaders, addressableManifest); Release(); return adapter; } public void Start() { if (_loadType == LoaderType.AssetBundle) { #if UNITY_EDITOR InitMainBundleEditor(); Result = Build(); Completed(); #elif UNITY_WEBGL || UNITY_WEIXINMINIGAME var bundlePath = FileUtils.GetAssetBundlePath(Define.MANIFEST_BUNDLE_FULLNAME); var request = UnityWebRequestAssetBundle.GetAssetBundle(bundlePath); var op = request.SendWebRequest(); op.completed += (_) => { if (!request.isDone || !op.isDone) { Debug.LogError($"Assetbundle error: manifest加载失败. request:{request.isDone} op:{op.isDone} Path:{bundlePath}"); Completed(); return; } var bundle = DownloadHandlerAssetBundle.GetContent(request); if (bundle == null) { Debug.LogError($"Assetbundle error: mainfest为空. {bundlePath}"); Completed(); return; } _mainbundle = bundle; Result = Build(); Completed(); }; #else _isBundleEncrypt = true; var bundlePath = FileUtils.GetAssetBundlePath(Define.MANIFEST_BUNDLE_FULLNAME); _mainbundle = AssetBundle.LoadFromFile(bundlePath, 0, Define.MANIFEST_BUNDLE_OFFSET);//"kcmanifest.bundle" Result = Build(); Completed(); #endif } else { Result = Build(); Completed(); } } } }