mirror of https://github.com/tuyoogame/YooAsset
parent
46467171ba
commit
9fbce6a726
|
@ -163,7 +163,7 @@ namespace YooAsset.Editor
|
||||||
|
|
||||||
// Status
|
// Status
|
||||||
StyleColor textColor;
|
StyleColor textColor;
|
||||||
if (bundleInfo.Status == AssetBundleLoader.EStatus.Fail)
|
if (bundleInfo.Status == AssetBundleLoaderBase.EStatus.Failed)
|
||||||
textColor = new StyleColor(Color.yellow);
|
textColor = new StyleColor(Color.yellow);
|
||||||
else
|
else
|
||||||
textColor = label1.style.color;
|
textColor = label1.style.color;
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace YooAsset
|
||||||
{
|
{
|
||||||
internal static class AssetSystem
|
internal static class AssetSystem
|
||||||
{
|
{
|
||||||
private static readonly List<AssetBundleLoader> _loaders = new List<AssetBundleLoader>(1000);
|
private static readonly List<AssetBundleLoaderBase> _loaders = new List<AssetBundleLoaderBase>(1000);
|
||||||
private static readonly List<ProviderBase> _providers = new List<ProviderBase>(1000);
|
private static readonly List<ProviderBase> _providers = new List<ProviderBase>(1000);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -90,12 +90,12 @@ namespace YooAsset
|
||||||
{
|
{
|
||||||
for (int i = _loaders.Count - 1; i >= 0; i--)
|
for (int i = _loaders.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
AssetBundleLoader loader = _loaders[i];
|
AssetBundleLoaderBase loader = _loaders[i];
|
||||||
loader.TryDestroyAllProviders();
|
loader.TryDestroyAllProviders();
|
||||||
}
|
}
|
||||||
for (int i = _loaders.Count - 1; i >= 0; i--)
|
for (int i = _loaders.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
AssetBundleLoader loader = _loaders[i];
|
AssetBundleLoaderBase loader = _loaders[i];
|
||||||
if (loader.CanDestroy())
|
if (loader.CanDestroy())
|
||||||
{
|
{
|
||||||
loader.Destroy(false);
|
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);
|
string bundleName = BundleServices.GetBundleName(assetPath);
|
||||||
BundleInfo bundleInfo = BundleServices.GetBundleInfo(bundleName);
|
BundleInfo bundleInfo = BundleServices.GetBundleInfo(bundleName);
|
||||||
return CreateAssetBundleLoaderInternal(bundleInfo);
|
return CreateAssetBundleLoaderInternal(bundleInfo);
|
||||||
}
|
}
|
||||||
internal static List<AssetBundleLoader> CreateDependAssetBundleLoaders(string assetPath)
|
internal static List<AssetBundleLoaderBase> CreateDependAssetBundleLoaders(string assetPath)
|
||||||
{
|
{
|
||||||
List<AssetBundleLoader> result = new List<AssetBundleLoader>();
|
List<AssetBundleLoaderBase> result = new List<AssetBundleLoaderBase>();
|
||||||
string[] depends = BundleServices.GetAllDependencies(assetPath);
|
string[] depends = BundleServices.GetAllDependencies(assetPath);
|
||||||
if (depends != null)
|
if (depends != null)
|
||||||
{
|
{
|
||||||
foreach (var dependBundleName in depends)
|
foreach (var dependBundleName in depends)
|
||||||
{
|
{
|
||||||
BundleInfo dependBundleInfo = BundleServices.GetBundleInfo(dependBundleName);
|
BundleInfo dependBundleInfo = BundleServices.GetBundleInfo(dependBundleName);
|
||||||
AssetBundleLoader dependLoader = CreateAssetBundleLoaderInternal(dependBundleInfo);
|
AssetBundleLoaderBase dependLoader = CreateAssetBundleLoaderInternal(dependBundleInfo);
|
||||||
result.Add(dependLoader);
|
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)
|
if (loader != null)
|
||||||
return loader;
|
return loader;
|
||||||
|
|
||||||
// 新增下载需求
|
// 新增下载需求
|
||||||
loader = new AssetBundleLoader(bundleInfo);
|
#if UNITY_WEBGL
|
||||||
|
loader = new AssetBundleWebLoader(bundleInfo);
|
||||||
|
#else
|
||||||
|
loader = new AssetBundleFileLoader(bundleInfo);
|
||||||
|
#endif
|
||||||
|
|
||||||
_loaders.Add(loader);
|
_loaders.Add(loader);
|
||||||
return 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++)
|
for (int i = 0; i < _loaders.Count; i++)
|
||||||
{
|
{
|
||||||
AssetBundleLoader temp = _loaders[i];
|
AssetBundleLoaderBase temp = _loaders[i];
|
||||||
if (temp.BundleFileInfo.BundleName.Equals(bundleName))
|
if (temp.BundleFileInfo.BundleName.Equals(bundleName))
|
||||||
{
|
{
|
||||||
loader = temp;
|
loader = temp;
|
||||||
|
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 轮询更新
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主线程等待异步操作完毕
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 资源包文件信息
|
|
||||||
/// </summary>
|
|
||||||
public BundleInfo BundleFileInfo { private set; get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 引用计数
|
|
||||||
/// </summary>
|
|
||||||
public int RefCount { private set; get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加载状态
|
|
||||||
/// </summary>
|
|
||||||
public EStatus Status { private set; get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否已经销毁
|
|
||||||
/// </summary>
|
|
||||||
public bool IsDestroyed { private set; get; } = false;
|
|
||||||
|
|
||||||
private readonly List<ProviderBase> _providers = new List<ProviderBase>(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 添加附属的资源提供者
|
|
||||||
/// </summary>
|
|
||||||
public void AddProvider(ProviderBase provider)
|
|
||||||
{
|
|
||||||
if (_providers.Contains(provider) == false)
|
|
||||||
_providers.Add(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 引用(引用计数递加)
|
|
||||||
/// </summary>
|
|
||||||
public void Reference()
|
|
||||||
{
|
|
||||||
RefCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 释放(引用计数递减)
|
|
||||||
/// </summary>
|
|
||||||
public void Release()
|
|
||||||
{
|
|
||||||
RefCount--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 轮询更新
|
|
||||||
/// </summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁
|
|
||||||
/// </summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否完毕(无论成功或失败)
|
|
||||||
/// </summary>
|
|
||||||
public bool IsDone()
|
|
||||||
{
|
|
||||||
return Status == EStatus.Success || Status == EStatus.Fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否可以销毁
|
|
||||||
/// </summary>
|
|
||||||
public bool CanDestroy()
|
|
||||||
{
|
|
||||||
if (IsDone() == false)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return RefCount <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在满足条件的前提下,销毁所有资源提供者
|
|
||||||
/// </summary>
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 主线程等待异步操作完毕
|
|
||||||
/// </summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源包文件信息
|
||||||
|
/// </summary>
|
||||||
|
public BundleInfo BundleFileInfo { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 引用计数
|
||||||
|
/// </summary>
|
||||||
|
public int RefCount { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载状态
|
||||||
|
/// </summary>
|
||||||
|
public EStatus Status { protected set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否已经销毁
|
||||||
|
/// </summary>
|
||||||
|
public bool IsDestroyed { private set; get; } = false;
|
||||||
|
|
||||||
|
private readonly List<ProviderBase> _providers = new List<ProviderBase>(100);
|
||||||
|
internal AssetBundle CacheBundle { set; get; }
|
||||||
|
|
||||||
|
|
||||||
|
public AssetBundleLoaderBase(BundleInfo bundleInfo)
|
||||||
|
{
|
||||||
|
BundleFileInfo = bundleInfo;
|
||||||
|
RefCount = 0;
|
||||||
|
Status = EStatus.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加附属的资源提供者
|
||||||
|
/// </summary>
|
||||||
|
public void AddProvider(ProviderBase provider)
|
||||||
|
{
|
||||||
|
if (_providers.Contains(provider) == false)
|
||||||
|
_providers.Add(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 引用(引用计数递加)
|
||||||
|
/// </summary>
|
||||||
|
public void Reference()
|
||||||
|
{
|
||||||
|
RefCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放(引用计数递减)
|
||||||
|
/// </summary>
|
||||||
|
public void Release()
|
||||||
|
{
|
||||||
|
RefCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 轮询更新
|
||||||
|
/// </summary>
|
||||||
|
public abstract void Update();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主线程等待异步操作完毕
|
||||||
|
/// </summary>
|
||||||
|
public abstract void WaitForAsyncComplete();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b8aaabc43e74af14d8eb3c7c85e19cda
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 轮询更新
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主线程等待异步操作完毕
|
||||||
|
/// </summary>
|
||||||
|
public override void WaitForAsyncComplete()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException($"WebGL platform not support {nameof(WaitForAsyncComplete)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bd1ad395c62c5804589ec9b267ea0484
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -9,7 +9,7 @@ namespace YooAsset
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 依赖的资源包加载器列表
|
/// 依赖的资源包加载器列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly List<AssetBundleLoader> _dependBundles;
|
private readonly List<AssetBundleLoaderBase> _dependBundles;
|
||||||
|
|
||||||
public DependAssetBundleGrouper(string assetPath)
|
public DependAssetBundleGrouper(string assetPath)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace YooAsset
|
||||||
{
|
{
|
||||||
internal abstract class BundledProvider : ProviderBase
|
internal abstract class BundledProvider : ProviderBase
|
||||||
{
|
{
|
||||||
protected AssetBundleLoader OwnerBundle { private set; get; }
|
protected AssetBundleLoaderBase OwnerBundle { private set; get; }
|
||||||
protected DependAssetBundleGrouper DependBundles { private set; get; }
|
protected DependAssetBundleGrouper DependBundles { private set; get; }
|
||||||
|
|
||||||
public BundledProvider(string assetPath, System.Type assetType) : base(assetPath, assetType)
|
public BundledProvider(string assetPath, System.Type assetType) : base(assetPath, assetType)
|
||||||
|
|
|
@ -21,6 +21,6 @@ namespace YooAsset
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加载状态
|
/// 加载状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public AssetBundleLoader.EStatus Status { set; get; }
|
public AssetBundleLoaderBase.EStatus Status { set; get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -61,7 +61,6 @@ namespace YooAsset
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string ConvertToWWWPath(string path)
|
public static string ConvertToWWWPath(string path)
|
||||||
{
|
{
|
||||||
// 注意:WWW加载方式,必须要在路径前面加file://
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
return StringUtility.Format("file:///{0}", path);
|
return StringUtility.Format("file:///{0}", path);
|
||||||
#elif UNITY_IPHONE
|
#elif UNITY_IPHONE
|
||||||
|
@ -70,6 +69,8 @@ namespace YooAsset
|
||||||
return path;
|
return path;
|
||||||
#elif UNITY_STANDALONE
|
#elif UNITY_STANDALONE
|
||||||
return StringUtility.Format("file:///{0}", path);
|
return StringUtility.Format("file:///{0}", path);
|
||||||
|
#elif UNITY_WEBGL
|
||||||
|
return path;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +204,6 @@ namespace YooAsset
|
||||||
/// 获取沙盒内补丁清单文件的哈希值
|
/// 获取沙盒内补丁清单文件的哈希值
|
||||||
/// 注意:如果沙盒内补丁清单文件不存在,返回空字符串
|
/// 注意:如果沙盒内补丁清单文件不存在,返回空字符串
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
|
||||||
public static string GetSandboxPatchManifestFileHash()
|
public static string GetSandboxPatchManifestFileHash()
|
||||||
{
|
{
|
||||||
string filePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.Setting.PatchManifestFileName);
|
string filePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.Setting.PatchManifestFileName);
|
||||||
|
|
|
@ -176,8 +176,12 @@ namespace YooAsset
|
||||||
// 初始化下载系统
|
// 初始化下载系统
|
||||||
if (_playMode == EPlayMode.HostPlayMode)
|
if (_playMode == EPlayMode.HostPlayMode)
|
||||||
{
|
{
|
||||||
|
#if UNITY_WEBGL
|
||||||
|
throw new Exception($"{EPlayMode.HostPlayMode} not supports WebGL platform !");
|
||||||
|
#else
|
||||||
var hostPlayModeParameters = parameters as HostPlayModeParameters;
|
var hostPlayModeParameters = parameters as HostPlayModeParameters;
|
||||||
DownloadSystem.Initialize(hostPlayModeParameters.BreakpointResumeFileSize);
|
DownloadSystem.Initialize(hostPlayModeParameters.BreakpointResumeFileSize);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化资源系统
|
// 初始化资源系统
|
||||||
|
|
Loading…
Reference in New Issue