From 9fbce6a726d0d46931bf566168c48302ccb6273c Mon Sep 17 00:00:00 2001 From: hevinci Date: Tue, 12 Apr 2022 10:53:12 +0800 Subject: [PATCH] offline play mode supports WebGL platform. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 离线运行模式支持WEBGL平台。 --- .../VisualViewers/BundleListDebuggerViewer.cs | 2 +- .../Runtime/AssetSystem/AssetSystem.cs | 31 +- .../Loader/AssetBundleFileLoader.cs | 183 +++++++++++ ....cs.meta => AssetBundleFileLoader.cs.meta} | 0 .../AssetSystem/Loader/AssetBundleLoader.cs | 301 ------------------ .../Loader/AssetBundleLoaderBase.cs | 155 +++++++++ .../Loader/AssetBundleLoaderBase.cs.meta | 11 + .../Loader/AssetBundleWebLoader.cs | 118 +++++++ .../Loader/AssetBundleWebLoader.cs.meta | 11 + .../Loader/DependAssetBundleGrouper.cs | 2 +- .../AssetSystem/Provider/BundledProvider.cs | 2 +- .../Runtime/Debugger/DebugBundleInfo.cs | 2 +- Assets/YooAsset/Runtime/Utility/YooHelper.cs | 4 +- Assets/YooAsset/Runtime/YooAssets.cs | 4 + 14 files changed, 506 insertions(+), 320 deletions(-) create mode 100644 Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs rename Assets/YooAsset/Runtime/AssetSystem/Loader/{AssetBundleLoader.cs.meta => AssetBundleFileLoader.cs.meta} (100%) delete mode 100644 Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoader.cs create mode 100644 Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs create mode 100644 Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs.meta create mode 100644 Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs create mode 100644 Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs.meta diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/BundleListDebuggerViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/BundleListDebuggerViewer.cs index 26aed74..eb0fb0b 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/BundleListDebuggerViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/BundleListDebuggerViewer.cs @@ -163,7 +163,7 @@ namespace YooAsset.Editor // Status StyleColor textColor; - if (bundleInfo.Status == AssetBundleLoader.EStatus.Fail) + if (bundleInfo.Status == AssetBundleLoaderBase.EStatus.Failed) textColor = new StyleColor(Color.yellow); else textColor = label1.style.color; diff --git a/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs b/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs index f46dbcd..5914d58 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs @@ -8,7 +8,7 @@ namespace YooAsset { internal static class AssetSystem { - private static readonly List _loaders = new List(1000); + private static readonly List _loaders = new List(1000); private static readonly List _providers = new List(1000); /// @@ -90,12 +90,12 @@ namespace YooAsset { for (int i = _loaders.Count - 1; i >= 0; i--) { - AssetBundleLoader loader = _loaders[i]; + AssetBundleLoaderBase loader = _loaders[i]; loader.TryDestroyAllProviders(); } for (int i = _loaders.Count - 1; i >= 0; i--) { - AssetBundleLoader loader = _loaders[i]; + AssetBundleLoaderBase loader = _loaders[i]; if (loader.CanDestroy()) { loader.Destroy(false); @@ -191,22 +191,22 @@ namespace YooAsset } - internal static AssetBundleLoader CreateOwnerAssetBundleLoader(string assetPath) + internal static AssetBundleLoaderBase CreateOwnerAssetBundleLoader(string assetPath) { string bundleName = BundleServices.GetBundleName(assetPath); BundleInfo bundleInfo = BundleServices.GetBundleInfo(bundleName); return CreateAssetBundleLoaderInternal(bundleInfo); } - internal static List CreateDependAssetBundleLoaders(string assetPath) + internal static List CreateDependAssetBundleLoaders(string assetPath) { - List result = new List(); + List result = new List(); string[] depends = BundleServices.GetAllDependencies(assetPath); if (depends != null) { foreach (var dependBundleName in depends) { BundleInfo dependBundleInfo = BundleServices.GetBundleInfo(dependBundleName); - AssetBundleLoader dependLoader = CreateAssetBundleLoaderInternal(dependBundleInfo); + AssetBundleLoaderBase dependLoader = CreateAssetBundleLoaderInternal(dependBundleInfo); result.Add(dependLoader); } } @@ -220,24 +220,29 @@ namespace YooAsset } } - private static AssetBundleLoader CreateAssetBundleLoaderInternal(BundleInfo bundleInfo) + private static AssetBundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo) { // 如果加载器已经存在 - AssetBundleLoader loader = TryGetAssetBundleLoader(bundleInfo.BundleName); + AssetBundleLoaderBase loader = TryGetAssetBundleLoader(bundleInfo.BundleName); if (loader != null) return loader; // 新增下载需求 - loader = new AssetBundleLoader(bundleInfo); +#if UNITY_WEBGL + loader = new AssetBundleWebLoader(bundleInfo); +#else + loader = new AssetBundleFileLoader(bundleInfo); +#endif + _loaders.Add(loader); return loader; } - private static AssetBundleLoader TryGetAssetBundleLoader(string bundleName) + private static AssetBundleLoaderBase TryGetAssetBundleLoader(string bundleName) { - AssetBundleLoader loader = null; + AssetBundleLoaderBase loader = null; for (int i = 0; i < _loaders.Count; i++) { - AssetBundleLoader temp = _loaders[i]; + AssetBundleLoaderBase temp = _loaders[i]; if (temp.BundleFileInfo.BundleName.Equals(bundleName)) { loader = temp; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs new file mode 100644 index 0000000..d1e449e --- /dev/null +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace YooAsset +{ + internal sealed class AssetBundleFileLoader : AssetBundleLoaderBase + { + private enum ESteps + { + None = 0, + Download, + CheckDownload, + LoadFile, + CheckFile, + Done, + } + + private ESteps _steps = ESteps.None; + private bool _isWaitForAsyncComplete = false; + private bool _isShowWaitForAsyncError = false; + private DownloaderBase _downloader; + private AssetBundleCreateRequest _cacheRequest; + + + public AssetBundleFileLoader(BundleInfo bundleInfo) : base(bundleInfo) + { + } + + /// + /// 轮询更新 + /// + public override void Update() + { + if (_steps == ESteps.Done) + return; + + if (_steps == ESteps.None) + { + // 检测加载地址是否为空 + if (string.IsNullOrEmpty(BundleFileInfo.LocalPath)) + { + _steps = ESteps.Done; + Status = EStatus.Failed; + return; + } + + if (string.IsNullOrEmpty(BundleFileInfo.RemoteMainURL)) + _steps = ESteps.LoadFile; + else + _steps = ESteps.Download; + } + + // 1. 从服务器下载 + if (_steps == ESteps.Download) + { + int failedTryAgain = int.MaxValue; + _downloader = DownloadSystem.BeginDownload(BundleFileInfo, failedTryAgain); + _steps = ESteps.CheckDownload; + } + + // 2. 检测服务器下载结果 + if (_steps == ESteps.CheckDownload) + { + if (_downloader.IsDone() == false) + return; + + if (_downloader.HasError()) + { + _downloader.ReportError(); + _steps = ESteps.Done; + Status = EStatus.Failed; + } + else + { + _steps = ESteps.LoadFile; + } + } + + // 3. 加载AssetBundle + if (_steps == ESteps.LoadFile) + { +#if UNITY_EDITOR + // 注意:Unity2017.4编辑器模式下,如果AssetBundle文件不存在会导致编辑器崩溃,这里做了预判。 + if (System.IO.File.Exists(BundleFileInfo.LocalPath) == false) + { + YooLogger.Warning($"Not found assetBundle file : {BundleFileInfo.LocalPath}"); + _steps = ESteps.Done; + Status = EStatus.Failed; + return; + } +#endif + + // Load assetBundle file + if (BundleFileInfo.IsEncrypted) + { + if (AssetSystem.DecryptionServices == null) + throw new Exception($"{nameof(AssetBundleFileLoader)} need IDecryptServices : {BundleFileInfo.BundleName}"); + + ulong offset = AssetSystem.DecryptionServices.GetFileOffset(BundleFileInfo); + if (_isWaitForAsyncComplete) + CacheBundle = AssetBundle.LoadFromFile(BundleFileInfo.LocalPath, 0, offset); + else + _cacheRequest = AssetBundle.LoadFromFileAsync(BundleFileInfo.LocalPath, 0, offset); + } + else + { + if (_isWaitForAsyncComplete) + CacheBundle = AssetBundle.LoadFromFile(BundleFileInfo.LocalPath); + else + _cacheRequest = AssetBundle.LoadFromFileAsync(BundleFileInfo.LocalPath); + } + _steps = ESteps.CheckFile; + } + + // 4. 检测AssetBundle加载结果 + if (_steps == ESteps.CheckFile) + { + if (_cacheRequest != null) + { + if (_isWaitForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + CacheBundle = _cacheRequest.assetBundle; + } + else + { + if (_cacheRequest.isDone == false) + return; + CacheBundle = _cacheRequest.assetBundle; + } + } + + // Check error + if (CacheBundle == null) + { + YooLogger.Error($"Failed to load assetBundle file : {BundleFileInfo.BundleName}"); + _steps = ESteps.Done; + Status = EStatus.Failed; + } + else + { + _steps = ESteps.Done; + Status = EStatus.Succeed; + } + } + } + + /// + /// 主线程等待异步操作完毕 + /// + public override void WaitForAsyncComplete() + { + _isWaitForAsyncComplete = true; + + int frame = 1000; + while (true) + { + // 保险机制 + // 注意:如果需要从WEB端下载资源,可能会触发保险机制! + frame--; + if (frame == 0) + { + if (_isShowWaitForAsyncError == false) + { + _isShowWaitForAsyncError = true; + YooLogger.Error($"WaitForAsyncComplete failed ! BundleName : {BundleFileInfo.BundleName} States : {Status}"); + } + break; + } + + // 驱动流程 + Update(); + + // 完成后退出 + if (IsDone()) + break; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoader.cs.meta b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoader.cs.meta rename to Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs.meta diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoader.cs deleted file mode 100644 index bead011..0000000 --- a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoader.cs +++ /dev/null @@ -1,301 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace YooAsset -{ - internal class AssetBundleLoader - { - public enum EStatus - { - None = 0, - Download, - CheckDownload, - LoadFile, - CheckFile, - Success, - Fail, - } - - /// - /// 资源包文件信息 - /// - public BundleInfo BundleFileInfo { private set; get; } - - /// - /// 引用计数 - /// - public int RefCount { private set; get; } - - /// - /// 加载状态 - /// - public EStatus Status { private set; get; } - - /// - /// 是否已经销毁 - /// - public bool IsDestroyed { private set; get; } = false; - - private readonly List _providers = new List(100); - private bool _isWaitForAsyncComplete = false; - private bool _isShowWaitForAsyncError = false; - private DownloaderBase _downloader; - private AssetBundleCreateRequest _cacheRequest; - internal AssetBundle CacheBundle { private set; get; } - - - public AssetBundleLoader(BundleInfo bundleInfo) - { - BundleFileInfo = bundleInfo; - RefCount = 0; - Status = EStatus.None; - } - - /// - /// 添加附属的资源提供者 - /// - public void AddProvider(ProviderBase provider) - { - if (_providers.Contains(provider) == false) - _providers.Add(provider); - } - - /// - /// 引用(引用计数递加) - /// - public void Reference() - { - RefCount++; - } - - /// - /// 释放(引用计数递减) - /// - public void Release() - { - RefCount--; - } - - /// - /// 轮询更新 - /// - public void Update() - { - // 如果资源文件加载完毕 - if (IsDone()) - return; - - if (Status == EStatus.None) - { - // 检测加载地址是否为空 - if (string.IsNullOrEmpty(BundleFileInfo.LocalPath)) - { - Status = EStatus.Fail; - return; - } - - if (string.IsNullOrEmpty(BundleFileInfo.RemoteMainURL)) - Status = EStatus.LoadFile; - else - Status = EStatus.Download; - } - - // 1. 从服务器下载 - if (Status == EStatus.Download) - { - int failedTryAgain = int.MaxValue; - _downloader = DownloadSystem.BeginDownload(BundleFileInfo, failedTryAgain); - Status = EStatus.CheckDownload; - } - - // 2. 检测服务器下载结果 - if (Status == EStatus.CheckDownload) - { - if (_downloader.IsDone() == false) - return; - - if (_downloader.HasError()) - { - _downloader.ReportError(); - Status = EStatus.Fail; - } - else - { - Status = EStatus.LoadFile; - } - } - - // 3. 加载AssetBundle - if (Status == EStatus.LoadFile) - { -#if UNITY_EDITOR - // 注意:Unity2017.4编辑器模式下,如果AssetBundle文件不存在会导致编辑器崩溃,这里做了预判。 - if (System.IO.File.Exists(BundleFileInfo.LocalPath) == false) - { - YooLogger.Warning($"Not found assetBundle file : {BundleFileInfo.LocalPath}"); - Status = EStatus.Fail; - return; - } -#endif - - // Load assetBundle file - if (BundleFileInfo.IsEncrypted) - { - if (AssetSystem.DecryptionServices == null) - throw new Exception($"{nameof(AssetBundleLoader)} need IDecryptServices : {BundleFileInfo.BundleName}"); - - ulong offset = AssetSystem.DecryptionServices.GetFileOffset(BundleFileInfo); - if (_isWaitForAsyncComplete) - CacheBundle = AssetBundle.LoadFromFile(BundleFileInfo.LocalPath, 0, offset); - else - _cacheRequest = AssetBundle.LoadFromFileAsync(BundleFileInfo.LocalPath, 0, offset); - } - else - { - if (_isWaitForAsyncComplete) - CacheBundle = AssetBundle.LoadFromFile(BundleFileInfo.LocalPath); - else - _cacheRequest = AssetBundle.LoadFromFileAsync(BundleFileInfo.LocalPath); - } - Status = EStatus.CheckFile; - } - - // 4. 检测AssetBundle加载结果 - if (Status == EStatus.CheckFile) - { - if (_cacheRequest != null) - { - if (_isWaitForAsyncComplete) - { - // 强制挂起主线程(注意:该操作会很耗时) - YooLogger.Warning("Suspend the main thread to load unity bundle."); - CacheBundle = _cacheRequest.assetBundle; - } - else - { - if (_cacheRequest.isDone == false) - return; - CacheBundle = _cacheRequest.assetBundle; - } - } - - // Check error - if (CacheBundle == null) - { - YooLogger.Error($"Failed to load assetBundle file : {BundleFileInfo.BundleName}"); - Status = EStatus.Fail; - } - else - { - Status = EStatus.Success; - } - } - } - - /// - /// 销毁 - /// - public void Destroy(bool forceDestroy) - { - IsDestroyed = true; - - // Check fatal - if (forceDestroy == false) - { - if (RefCount > 0) - throw new Exception($"Bundle file loader ref is not zero : {BundleFileInfo.BundleName}"); - if (IsDone() == false) - throw new Exception($"Bundle file loader is not done : {BundleFileInfo.BundleName}"); - } - - if (CacheBundle != null) - { - CacheBundle.Unload(true); - CacheBundle = null; - } - } - - /// - /// 是否完毕(无论成功或失败) - /// - public bool IsDone() - { - return Status == EStatus.Success || Status == EStatus.Fail; - } - - /// - /// 是否可以销毁 - /// - public bool CanDestroy() - { - if (IsDone() == false) - return false; - - return RefCount <= 0; - } - - /// - /// 在满足条件的前提下,销毁所有资源提供者 - /// - public void TryDestroyAllProviders() - { - if (IsDone() == false) - return; - - // 注意:必须等待所有Provider可以销毁的时候,才可以释放Bundle文件。 - foreach (var provider in _providers) - { - if (provider.CanDestroy() == false) - return; - } - - // 除了自己没有其它引用 - if (RefCount > _providers.Count) - return; - - // 销毁所有Providers - foreach (var provider in _providers) - { - provider.Destory(); - } - - // 从列表里移除Providers - AssetSystem.RemoveBundleProviders(_providers); - _providers.Clear(); - } - - /// - /// 主线程等待异步操作完毕 - /// - public void WaitForAsyncComplete() - { - _isWaitForAsyncComplete = true; - - int frame = 1000; - while (true) - { - // 保险机制 - // 注意:如果需要从WEB端下载资源,可能会触发保险机制! - frame--; - if (frame == 0) - { - if (_isShowWaitForAsyncError == false) - { - _isShowWaitForAsyncError = true; - YooLogger.Error($"WaitForAsyncComplete failed ! BundleName : {BundleFileInfo.BundleName} States : {Status}"); - } - break; - } - - // 驱动流程 - Update(); - - // 完成后退出 - if (IsDone()) - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs new file mode 100644 index 0000000..495a062 --- /dev/null +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace YooAsset +{ + internal abstract class AssetBundleLoaderBase + { + public enum EStatus + { + None = 0, + Succeed, + Failed + } + + /// + /// 资源包文件信息 + /// + public BundleInfo BundleFileInfo { private set; get; } + + /// + /// 引用计数 + /// + public int RefCount { private set; get; } + + /// + /// 加载状态 + /// + public EStatus Status { protected set; get; } + + /// + /// 是否已经销毁 + /// + public bool IsDestroyed { private set; get; } = false; + + private readonly List _providers = new List(100); + internal AssetBundle CacheBundle { set; get; } + + + public AssetBundleLoaderBase(BundleInfo bundleInfo) + { + BundleFileInfo = bundleInfo; + RefCount = 0; + Status = EStatus.None; + } + + /// + /// 添加附属的资源提供者 + /// + public void AddProvider(ProviderBase provider) + { + if (_providers.Contains(provider) == false) + _providers.Add(provider); + } + + /// + /// 引用(引用计数递加) + /// + public void Reference() + { + RefCount++; + } + + /// + /// 释放(引用计数递减) + /// + public void Release() + { + RefCount--; + } + + /// + /// 轮询更新 + /// + public abstract void Update(); + + /// + /// 销毁 + /// + public void Destroy(bool forceDestroy) + { + IsDestroyed = true; + + // Check fatal + if (forceDestroy == false) + { + if (RefCount > 0) + throw new Exception($"Bundle file loader ref is not zero : {BundleFileInfo.BundleName}"); + if (IsDone() == false) + throw new Exception($"Bundle file loader is not done : {BundleFileInfo.BundleName}"); + } + + if (CacheBundle != null) + { + CacheBundle.Unload(true); + CacheBundle = null; + } + } + + /// + /// 是否完毕(无论成功或失败) + /// + public bool IsDone() + { + return Status == EStatus.Succeed || Status == EStatus.Failed; + } + + /// + /// 是否可以销毁 + /// + public bool CanDestroy() + { + if (IsDone() == false) + return false; + + return RefCount <= 0; + } + + /// + /// 在满足条件的前提下,销毁所有资源提供者 + /// + public void TryDestroyAllProviders() + { + if (IsDone() == false) + return; + + // 注意:必须等待所有Provider可以销毁的时候,才可以释放Bundle文件。 + foreach (var provider in _providers) + { + if (provider.CanDestroy() == false) + return; + } + + // 除了自己没有其它引用 + if (RefCount > _providers.Count) + return; + + // 销毁所有Providers + foreach (var provider in _providers) + { + provider.Destory(); + } + + // 从列表里移除Providers + AssetSystem.RemoveBundleProviders(_providers); + _providers.Clear(); + } + + /// + /// 主线程等待异步操作完毕 + /// + public abstract void WaitForAsyncComplete(); + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs.meta b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs.meta new file mode 100644 index 0000000..5cd8fa4 --- /dev/null +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8aaabc43e74af14d8eb3c7c85e19cda +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs new file mode 100644 index 0000000..a3df0e4 --- /dev/null +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Networking; + +namespace YooAsset +{ + internal sealed class AssetBundleWebLoader : AssetBundleLoaderBase + { + private enum ESteps + { + None = 0, + LoadFile, + CheckFile, + TryLoad, + Done, + } + + private ESteps _steps = ESteps.None; + private float _tryTimer = 0; + private string _webURL; + private UnityWebRequest _webRequest; + + + public AssetBundleWebLoader(BundleInfo bundleInfo) : base(bundleInfo) + { + } + + /// + /// 轮询更新 + /// + public override void Update() + { + if (_steps == ESteps.Done) + return; + + if (_steps == ESteps.None) + { + // 检测加载地址是否为空 + if (string.IsNullOrEmpty(BundleFileInfo.LocalPath)) + { + _steps = ESteps.Done; + Status = EStatus.Failed; + return; + } + + if (string.IsNullOrEmpty(BundleFileInfo.RemoteMainURL)) + _webURL = BundleFileInfo.LocalPath; + else + _webURL = BundleFileInfo.RemoteMainURL; + _steps = ESteps.LoadFile; + } + + // 1. 从服务器或缓存中获取AssetBundle文件 + if (_steps == ESteps.LoadFile) + { + string hash = StringUtility.RemoveExtension(BundleFileInfo.Hash); + _webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_webURL, Hash128.Parse(hash)); + _webRequest.SendWebRequest(); + _steps = ESteps.CheckFile; + } + + // 2. 检测获取的AssetBundle文件 + if (_steps == ESteps.CheckFile) + { + if (_webRequest.isDone == false) + return; + +#if UNITY_2020_1_OR_NEWER + if (_webRequest.result != UnityWebRequest.Result.Success) +#else + if (_webRequest.isNetworkError || _webRequest.isHttpError) +#endif + { + Debug.LogWarning($"Failed to get asset bundle form web : {_webURL} Error : {_webRequest.error}"); + _steps = ESteps.TryLoad; + _tryTimer = 0; + } + else + { + CacheBundle = DownloadHandlerAssetBundle.GetContent(_webRequest); + if (CacheBundle == null) + { + Debug.LogError($"Get asset bundle error : {_webRequest.error}"); + _steps = ESteps.Done; + Status = EStatus.Failed; + } + else + { + _steps = ESteps.Done; + Status = EStatus.Succeed; + } + } + } + + // 3. 如果获取失败,重新尝试 + if (_steps == ESteps.TryLoad) + { + _tryTimer += Time.unscaledDeltaTime; + if (_tryTimer > 1f) + { + _webRequest.Dispose(); + _webRequest = null; + _steps = ESteps.LoadFile; + } + } + } + + /// + /// 主线程等待异步操作完毕 + /// + public override void WaitForAsyncComplete() + { + throw new System.NotImplementedException($"WebGL platform not support {nameof(WaitForAsyncComplete)}"); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs.meta b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs.meta new file mode 100644 index 0000000..3b5e44b --- /dev/null +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd1ad395c62c5804589ec9b267ea0484 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/DependAssetBundleGrouper.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/DependAssetBundleGrouper.cs index b704834..1ecd972 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Loader/DependAssetBundleGrouper.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/DependAssetBundleGrouper.cs @@ -9,7 +9,7 @@ namespace YooAsset /// /// 依赖的资源包加载器列表 /// - private readonly List _dependBundles; + private readonly List _dependBundles; public DependAssetBundleGrouper(string assetPath) { diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs index 59bb8bf..5b73460 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledProvider.cs @@ -5,7 +5,7 @@ namespace YooAsset { internal abstract class BundledProvider : ProviderBase { - protected AssetBundleLoader OwnerBundle { private set; get; } + protected AssetBundleLoaderBase OwnerBundle { private set; get; } protected DependAssetBundleGrouper DependBundles { private set; get; } public BundledProvider(string assetPath, System.Type assetType) : base(assetPath, assetType) diff --git a/Assets/YooAsset/Runtime/Debugger/DebugBundleInfo.cs b/Assets/YooAsset/Runtime/Debugger/DebugBundleInfo.cs index 3d705d4..9cff6bd 100644 --- a/Assets/YooAsset/Runtime/Debugger/DebugBundleInfo.cs +++ b/Assets/YooAsset/Runtime/Debugger/DebugBundleInfo.cs @@ -21,6 +21,6 @@ namespace YooAsset /// /// 加载状态 /// - public AssetBundleLoader.EStatus Status { set; get; } + public AssetBundleLoaderBase.EStatus Status { set; get; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/YooHelper.cs b/Assets/YooAsset/Runtime/Utility/YooHelper.cs index f84a824..244181d 100644 --- a/Assets/YooAsset/Runtime/Utility/YooHelper.cs +++ b/Assets/YooAsset/Runtime/Utility/YooHelper.cs @@ -61,7 +61,6 @@ namespace YooAsset /// public static string ConvertToWWWPath(string path) { - // 注意:WWW加载方式,必须要在路径前面加file:// #if UNITY_EDITOR return StringUtility.Format("file:///{0}", path); #elif UNITY_IPHONE @@ -70,6 +69,8 @@ namespace YooAsset return path; #elif UNITY_STANDALONE return StringUtility.Format("file:///{0}", path); +#elif UNITY_WEBGL + return path; #endif } @@ -203,7 +204,6 @@ namespace YooAsset /// 获取沙盒内补丁清单文件的哈希值 /// 注意:如果沙盒内补丁清单文件不存在,返回空字符串 /// - /// public static string GetSandboxPatchManifestFileHash() { string filePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.Setting.PatchManifestFileName); diff --git a/Assets/YooAsset/Runtime/YooAssets.cs b/Assets/YooAsset/Runtime/YooAssets.cs index ef84d9e..62c7efe 100644 --- a/Assets/YooAsset/Runtime/YooAssets.cs +++ b/Assets/YooAsset/Runtime/YooAssets.cs @@ -176,8 +176,12 @@ namespace YooAsset // 初始化下载系统 if (_playMode == EPlayMode.HostPlayMode) { +#if UNITY_WEBGL + throw new Exception($"{EPlayMode.HostPlayMode} not supports WebGL platform !"); +#else var hostPlayModeParameters = parameters as HostPlayModeParameters; DownloadSystem.Initialize(hostPlayModeParameters.BreakpointResumeFileSize); +#endif } // 初始化资源系统