更新demo

更新demo
This commit is contained in:
ALEXTANG
2024-03-18 15:35:15 +08:00
parent 17a5d7425c
commit a2255b80cd
1028 changed files with 55353 additions and 35278 deletions

View File

@@ -0,0 +1,294 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class AssetBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None = 0,
Download,
CheckDownload,
Unpack,
CheckUnpack,
LoadBundleFile,
LoadDeliveryFile,
CheckLoadFile,
Done,
}
private ESteps _steps = ESteps.None;
private bool _isWaitForAsyncComplete = false;
private bool _isShowWaitForAsyncError = false;
private DownloaderBase _unpacker;
private DownloaderBase _downloader;
private AssetBundleCreateRequest _createRequest;
private Stream _managedStream;
public AssetBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
#if UNITY_ANDROID
if (MainBundleInfo.Bundle.Encrypted)
{
_steps = ESteps.Unpack;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else
{
_steps = ESteps.LoadBundleFile;
FileLoadPath = MainBundleInfo.BuildinFilePath;
}
#else
_steps = ESteps.LoadBundleFile;
FileLoadPath = MainBundleInfo.BuildinFilePath;
#endif
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.LoadBundleFile;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery)
{
_steps = ESteps.LoadDeliveryFile;
FileLoadPath = MainBundleInfo.DeliveryFilePath;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 从服务器下载
if (_steps == ESteps.Download)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest();
_steps = ESteps.CheckDownload;
}
// 2. 检测服务器下载结果
if (_steps == ESteps.CheckDownload)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _downloader.GetLastError();
}
else
{
_steps = ESteps.LoadBundleFile;
return; //下载完毕等待一帧再去加载!
}
}
// 3. 内置文件解压
if (_steps == ESteps.Unpack)
{
int failedTryAgain = 1;
_unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain);
_unpacker.SendRequest();
_steps = ESteps.CheckUnpack;
}
// 4.检测内置文件解压结果
if (_steps == ESteps.CheckUnpack)
{
DownloadProgress = _unpacker.DownloadProgress;
DownloadedBytes = _unpacker.DownloadedBytes;
if (_unpacker.IsDone() == false)
return;
if (_unpacker.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _unpacker.GetLastError();
}
else
{
_steps = ESteps.LoadBundleFile;
}
}
// 5. 加载AssetBundle
if (_steps == ESteps.LoadBundleFile)
{
#if UNITY_EDITOR
// 注意Unity2017.4编辑器模式下如果AssetBundle文件不存在会导致编辑器崩溃这里做了预判。
if (System.IO.File.Exists(FileLoadPath) == false)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Not found assetBundle file : {FileLoadPath}";
YooLogger.Error(LastError);
return;
}
#endif
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
// 加载AssetBundle资源对象
// 注意:解密服务类可能会返回空的对象。
if (_isWaitForAsyncComplete)
CacheBundle = MainBundleInfo.LoadAssetBundle(FileLoadPath, out _managedStream);
else
_createRequest = MainBundleInfo.LoadAssetBundleAsync(FileLoadPath, out _managedStream);
_steps = ESteps.CheckLoadFile;
}
// 6. 加载AssetBundle
if (_steps == ESteps.LoadDeliveryFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
// Load assetBundle file
if (_isWaitForAsyncComplete)
CacheBundle = MainBundleInfo.LoadDeliveryAssetBundle(FileLoadPath);
else
_createRequest = MainBundleInfo.LoadDeliveryAssetBundleAsync(FileLoadPath);
_steps = ESteps.CheckLoadFile;
}
// 7. 检测AssetBundle加载结果
if (_steps == ESteps.CheckLoadFile)
{
if (_createRequest != null)
{
if (_isWaitForAsyncComplete || IsForceDestroyComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity bundle.");
CacheBundle = _createRequest.assetBundle;
}
else
{
if (_createRequest.isDone == false)
return;
CacheBundle = _createRequest.assetBundle;
}
}
// Check error
if (CacheBundle == null)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Failed to load assetBundle : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
// 注意当缓存文件的校验等级为Low的时候并不能保证缓存文件的完整性。
// 在AssetBundle文件加载失败的情况下我们需要重新验证文件的完整性
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
var result = MainBundleInfo.VerifySelf();
if (result != EVerifyResult.Succeed)
{
YooLogger.Error($"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID} Verify result : {result}");
MainBundleInfo.CacheDiscard();
}
}
}
else
{
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
}
}
/// <summary>
/// 销毁
/// </summary>
public override void Destroy()
{
base.Destroy();
if (_managedStream != null)
{
_managedStream.Close();
_managedStream.Dispose();
_managedStream = null;
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
_isWaitForAsyncComplete = true;
int frame = 1000;
while (true)
{
// 文件解压
if (_unpacker != null)
{
if (_unpacker.IsDone() == false)
{
_unpacker.WaitForAsyncComplete = true;
_unpacker.Update();
continue;
}
}
// 保险机制
// 注意如果需要从WEB端下载资源可能会触发保险机制
frame--;
if (frame == 0)
{
if (_isShowWaitForAsyncError == false)
{
_isShowWaitForAsyncError = true;
YooLogger.Error($"{nameof(WaitForAsyncComplete)} failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !");
}
break;
}
// 驱动流程
Update();
// 完成后退出
if (IsDone())
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 64d0a51f59c2a964eaf97b87db47428f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,111 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
namespace YooAsset
{
/// <summary>
/// WebGL平台加载器
/// </summary>
internal sealed class AssetBundleWebLoader : BundleLoaderBase
{
private enum ESteps
{
None = 0,
LoadWebSiteFile,
LoadRemoteFile,
CheckLoadFile,
Done,
}
private ESteps _steps = ESteps.None;
private DownloaderBase _downloader;
public AssetBundleWebLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.LoadRemoteFile;
FileLoadPath = string.Empty;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.LoadWebSiteFile;
FileLoadPath = string.Empty;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 跨域获取资源包
if (_steps == ESteps.LoadRemoteFile)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest(true);
_steps = ESteps.CheckLoadFile;
}
// 2. 从站点获取资源包
if (_steps == ESteps.LoadWebSiteFile)
{
_downloader = MainBundleInfo.CreateUnpacker(int.MaxValue);
_downloader.SendRequest(true);
_steps = ESteps.CheckLoadFile;
}
// 3. 检测加载结果
if (_steps == ESteps.CheckLoadFile)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
CacheBundle = _downloader.GetAssetBundle();
if (CacheBundle == null)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"AssetBundle file is invalid : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
else
{
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
if (IsDone() == false)
{
Status = EStatus.Failed;
LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !";
YooLogger.Error(LastError);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bd1ad395c62c5804589ec9b267ea0484
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,181 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal abstract class BundleLoaderBase
{
public enum EStatus
{
None = 0,
Succeed,
Failed
}
/// <summary>
/// 所属资源系统
/// </summary>
public ResourceManager Impl { private set; get; }
/// <summary>
/// 资源包文件信息
/// </summary>
public BundleInfo MainBundleInfo { private set; get; }
/// <summary>
/// 引用计数
/// </summary>
public int RefCount { private set; get; }
/// <summary>
/// 加载状态
/// </summary>
public EStatus Status { protected set; get; }
/// <summary>
/// 最近的错误信息
/// </summary>
public string LastError { protected set; get; }
/// <summary>
/// 是否已经销毁
/// </summary>
public bool IsDestroyed { private set; get; } = false;
private readonly List<ProviderBase> _providers = new List<ProviderBase>(100);
private readonly List<ProviderBase> _removeList = new List<ProviderBase>(100);
protected bool IsForceDestroyComplete { private set; get; } = false;
internal AssetBundle CacheBundle { set; get; }
internal string FileLoadPath { set; get; }
internal float DownloadProgress { set; get; }
internal ulong DownloadedBytes { set; get; }
public BundleLoaderBase(ResourceManager impl, BundleInfo bundleInfo)
{
Impl = impl;
MainBundleInfo = bundleInfo;
RefCount = 0;
Status = EStatus.None;
}
/// <summary>
/// 引用(引用计数递加)
/// </summary>
public void Reference()
{
RefCount++;
}
/// <summary>
/// 释放(引用计数递减)
/// </summary>
public void Release()
{
RefCount--;
}
/// <summary>
/// 是否完毕(无论成功或失败)
/// </summary>
public bool IsDone()
{
return Status == EStatus.Succeed || Status == EStatus.Failed;
}
/// <summary>
/// 是否可以销毁
/// </summary>
public bool CanDestroy()
{
if (IsDone() == false)
return false;
return RefCount <= 0;
}
/// <summary>
/// 添加附属的资源提供者
/// </summary>
public void AddProvider(ProviderBase provider)
{
if (_providers.Contains(provider) == false)
_providers.Add(provider);
}
/// <summary>
/// 尝试销毁资源提供者
/// </summary>
public void TryDestroyProviders()
{
// 获取移除列表
_removeList.Clear();
foreach (var provider in _providers)
{
if (provider.CanDestroy())
{
_removeList.Add(provider);
}
}
// 销毁资源提供者
foreach (var provider in _removeList)
{
_providers.Remove(provider);
provider.Destroy();
}
// 移除资源提供者
if (_removeList.Count > 0)
{
Impl.RemoveBundleProviders(_removeList);
_removeList.Clear();
}
}
/// <summary>
/// 轮询更新
/// </summary>
public abstract void Update();
/// <summary>
/// 销毁
/// </summary>
public virtual void Destroy()
{
IsDestroyed = true;
// Check fatal
if (RefCount > 0)
throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.Bundle.BundleName}");
if (IsDone() == false)
throw new Exception($"Bundle file loader is not done : {MainBundleInfo.Bundle.BundleName}");
if (CacheBundle != null)
{
CacheBundle.Unload(true);
CacheBundle = null;
}
}
/// <summary>
/// 强制销毁资源提供者
/// </summary>
public void ForceDestroyComplete()
{
IsForceDestroyComplete = true;
// 注意:主动轮询更新完成同步加载
// 说明:如果正在下载或解压也可以放心销毁。
Update();
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public abstract void WaitForAsyncComplete();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b8aaabc43e74af14d8eb3c7c85e19cda
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,112 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace YooAsset
{
internal class DependAssetBundles
{
/// <summary>
/// 依赖的资源包加载器列表
/// </summary>
internal readonly List<BundleLoaderBase> DependList;
public DependAssetBundles(List<BundleLoaderBase> dpendList)
{
DependList = dpendList;
}
/// <summary>
/// 是否已经完成(无论成功或失败)
/// </summary>
public bool IsDone()
{
foreach (var loader in DependList)
{
if (loader.IsDone() == false)
return false;
}
return true;
}
/// <summary>
/// 依赖资源包是否全部加载成功
/// </summary>
public bool IsSucceed()
{
foreach (var loader in DependList)
{
if (loader.Status != BundleLoaderBase.EStatus.Succeed)
{
return false;
}
}
return true;
}
/// <summary>
/// 获取某个加载失败的资源包错误信息
/// </summary>
public string GetLastError()
{
foreach (var loader in DependList)
{
if (loader.Status != BundleLoaderBase.EStatus.Succeed)
{
return loader.LastError;
}
}
return string.Empty;
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public void WaitForAsyncComplete()
{
foreach (var loader in DependList)
{
if (loader.IsDone() == false)
loader.WaitForAsyncComplete();
}
}
/// <summary>
/// 增加引用计数
/// </summary>
public void Reference()
{
foreach (var loader in DependList)
{
loader.Reference();
}
}
/// <summary>
/// 减少引用计数
/// </summary>
public void Release()
{
foreach (var loader in DependList)
{
loader.Release();
}
}
/// <summary>
/// 获取资源包的调试信息列表
/// </summary>
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{
foreach (var loader in DependList)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = loader.MainBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = loader.RefCount;
bundleInfo.Status = loader.Status.ToString();
output.Add(bundleInfo);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b7eeccc96e4c31c45bd105b0dbc3fd6e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,188 @@
using System.IO;
namespace YooAsset
{
internal class RawBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None,
Download,
CheckDownload,
Unpack,
CheckUnpack,
CheckFile,
Done,
}
private ESteps _steps = ESteps.None;
private DownloaderBase _unpacker;
private DownloaderBase _downloader;
public RawBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
#if UNITY_ANDROID
_steps = ESteps.Unpack;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
#else
_steps = ESteps.CheckFile;
FileLoadPath = MainBundleInfo.BuildinFilePath;
#endif
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.CheckFile;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery)
{
_steps = ESteps.CheckFile;
FileLoadPath = MainBundleInfo.DeliveryFilePath;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 下载远端文件
if (_steps == ESteps.Download)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest();
_steps = ESteps.CheckDownload;
}
// 2. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _downloader.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
// 3. 解压内置文件
if (_steps == ESteps.Unpack)
{
int failedTryAgain = 1;
_unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain);
_unpacker.SendRequest();
_steps = ESteps.CheckUnpack;
}
// 4. 检测解压结果
if (_steps == ESteps.CheckUnpack)
{
DownloadProgress = _unpacker.DownloadProgress;
DownloadedBytes = _unpacker.DownloadedBytes;
if (_unpacker.IsDone() == false)
return;
if (_unpacker.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _unpacker.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
// 5. 检测结果
if (_steps == ESteps.CheckFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
if (File.Exists(FileLoadPath))
{
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Raw file not found : {FileLoadPath}";
}
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
int frame = 1000;
while (true)
{
// 文件解压
if (_unpacker != null)
{
if (_unpacker.IsDone() == false)
{
_unpacker.WaitForAsyncComplete = true;
_unpacker.Update();
continue;
}
}
// 保险机制
// 注意:如果需要从远端下载资源,可能会触发保险机制!
frame--;
if (frame == 0)
{
if (IsDone() == false)
{
Status = EStatus.Failed;
LastError = $"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !";
YooLogger.Error(LastError);
}
break;
}
// 驱动流程
Update();
// 完成后退出
if (IsDone())
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fa39f24727abe514093f18787c0c7e27
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,145 @@
using System.IO;
namespace YooAsset
{
/// <summary>
/// WebGL平台加载器
/// </summary>
internal class RawBundleWebLoader : BundleLoaderBase
{
private enum ESteps
{
None,
Download,
CheckDownload,
Website,
CheckWebsite,
CheckFile,
Done,
}
private ESteps _steps = ESteps.None;
private DownloaderBase _website;
private DownloaderBase _downloader;
public RawBundleWebLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.Website;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 下载远端文件
if (_steps == ESteps.Download)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest();
_steps = ESteps.CheckDownload;
}
// 2. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _downloader.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
// 3. 从站点下载
if (_steps == ESteps.Website)
{
_website = MainBundleInfo.CreateUnpacker(int.MaxValue);
_website.SendRequest();
_steps = ESteps.CheckWebsite;
}
// 4. 检测站点下载
if (_steps == ESteps.CheckWebsite)
{
DownloadProgress = _website.DownloadProgress;
DownloadedBytes = _website.DownloadedBytes;
if (_website.IsDone() == false)
return;
if (_website.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _website.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
// 5. 检测结果
if (_steps == ESteps.CheckFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
_steps = ESteps.Done;
if (File.Exists(FileLoadPath))
{
Status = EStatus.Succeed;
}
else
{
Status = EStatus.Failed;
LastError = $"Raw file not found : {FileLoadPath}";
}
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
if (IsDone() == false)
{
Status = EStatus.Failed;
LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !";
YooLogger.Error(LastError);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1d16b689f73611e44bd01a4cc429a6ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@

namespace YooAsset
{
internal class VirtualBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None,
CheckFile,
Done,
}
private ESteps _steps = ESteps.None;
public VirtualBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromEditor)
{
_steps = ESteps.CheckFile;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 检测结果
if (_steps == ESteps.CheckFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
int frame = 1000;
while (true)
{
// 保险机制
// 注意:如果需要从远端下载资源,可能会触发保险机制!
frame--;
if (frame == 0)
{
if (IsDone() == false)
{
Status = EStatus.Failed;
LastError = $"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !";
YooLogger.Error(LastError);
}
break;
}
// 驱动流程
Update();
// 完成后退出
if (IsDone())
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7b9023a940b496549894d9d8872219fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: