246 lines
8.6 KiB
C#
246 lines
8.6 KiB
C#
using UnityEngine;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
|
||
namespace BF
|
||
{
|
||
public class AssetBundleObject : AssetObjectBase
|
||
{
|
||
public static Dictionary<string, string> fullpathDict = new Dictionary<string, string>();
|
||
public AssetBundleConfig AssetBundleConfig { get; private set; }
|
||
|
||
public AssetBundle Assetbundle { get; private set; }
|
||
|
||
private AssetBundleCreateRequest request;
|
||
|
||
private BFEvent<AssetBundleObject> loadComplete;
|
||
|
||
private BFEvent unloadComplete;
|
||
|
||
public float Timeout { get; private set; } //异步加载的超时机制,保证不会一直卡在这里
|
||
|
||
private int recordDependCount;
|
||
|
||
private string[] dependAB;
|
||
|
||
private AssetBundleLoader assetBundleLoader;
|
||
|
||
private bool dependABComplete = false;
|
||
|
||
public AssetBundleObject(AssetBundleConfig config, AssetBundleLoader loader) : base(config.assetBundlePath, null)
|
||
{
|
||
AssetBundleConfig = config;
|
||
assetBundleLoader = loader;
|
||
loadComplete = new BFEvent<AssetBundleObject>();
|
||
unloadComplete = new BFEvent();
|
||
dependAB = loader.Manifest.GetAllDependencies(config.assetBundlePath);
|
||
dependABComplete = dependAB.Length == 0;
|
||
recordDependCount = dependAB.Length;
|
||
for (int i = 0; i < dependAB.Length; i++)
|
||
{
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] [AssetBundleObject] assetpath : {2} index : {0}, depend : {1}", i, dependAB[i], AssetPath);
|
||
assetBundleLoader.LoadDependBundleAsync(dependAB[i], LoadCompleteDepenedAsset);
|
||
}
|
||
}
|
||
|
||
public void LoadBundleAsync(Action<AssetBundleObject> callback)
|
||
{
|
||
++RefCount;
|
||
if (EAssetLoadStatus.Complete == LoadStatus || EAssetLoadStatus.Error == LoadStatus)
|
||
{
|
||
callback(this);
|
||
}
|
||
else if (EAssetLoadStatus.Unloading == LoadStatus)
|
||
{
|
||
LoadStatus = EAssetLoadStatus.Complete;
|
||
callback(this);
|
||
}
|
||
else
|
||
{
|
||
loadComplete += callback;
|
||
}
|
||
}
|
||
|
||
public void StartLoadAsync()
|
||
{
|
||
LoadStatus = EAssetLoadStatus.Loading;
|
||
|
||
if (!fullpathDict.TryGetValue(AssetPath, out string fullpath))
|
||
{
|
||
if (AssetBundleConfig.location == 1)
|
||
{
|
||
fullpath = Path.Combine(Application.persistentDataPath, "update", AssetPath);
|
||
}
|
||
else
|
||
{
|
||
fullpath = Path.Combine(Application.streamingAssetsPath, AssetPath);
|
||
}
|
||
fullpathDict.Add(AssetPath, fullpath);
|
||
}
|
||
request = AssetBundle.LoadFromFileAsync(fullpath);
|
||
Timeout = ResourceManager.TIME_OUT_LOAD + Time.time;
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "StartLoadAsync assetpath : {0}. timeout : {1}", fullpath, Timeout);
|
||
}
|
||
|
||
public void LoadSync(bool ignoreRefCount = false)
|
||
{
|
||
if (!ignoreRefCount)
|
||
{
|
||
++RefCount;
|
||
}
|
||
|
||
if(EAssetLoadStatus.Complete == LoadStatus)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (EAssetLoadStatus.Loading != LoadStatus)
|
||
{
|
||
for (int i = 0; i < dependAB.Length; i++)
|
||
{
|
||
assetBundleLoader.LoadDependBundleSync(dependAB[i]);
|
||
}
|
||
|
||
if (!fullpathDict.TryGetValue(AssetPath, out string fullpath))
|
||
{
|
||
if (AssetBundleConfig.location == 1)
|
||
{
|
||
fullpath = Path.Combine(Application.persistentDataPath, "update", AssetPath);
|
||
}
|
||
else
|
||
{
|
||
fullpath = Path.Combine(Application.streamingAssetsPath, AssetPath);
|
||
}
|
||
fullpathDict.Add(AssetPath, fullpath);
|
||
}
|
||
var ab = AssetBundle.LoadFromFile(fullpath);
|
||
Complete(ab);
|
||
}
|
||
else
|
||
{
|
||
// 异步过程中转同步
|
||
for (int i = 0; i < dependAB.Length; i++)
|
||
{
|
||
assetBundleLoader.LoadDependBundleSync(dependAB[i]);
|
||
}
|
||
var ab = request.assetBundle;
|
||
Complete(ab);
|
||
}
|
||
}
|
||
|
||
private void LoadCompleteDepenedAsset(AssetBundleObject assetBundleObject)
|
||
{
|
||
recordDependCount--;
|
||
if (recordDependCount == 0)
|
||
{
|
||
dependABComplete = true;
|
||
}
|
||
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[AssetBundleObject] [LoadCompleteDepenedAsset] : {0}, record dependent count : {1}", assetBundleObject.AssetPath, recordDependCount);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载完成,返回true, 否则返回false. 超时机制确保不会无法结束
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public override bool Tick()
|
||
{
|
||
try
|
||
{
|
||
if (EAssetLoadStatus.Loading == LoadStatus)
|
||
{
|
||
if (request != null && request.isDone && dependABComplete)
|
||
{
|
||
Complete(request.assetBundle);
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
if (Timeout < Time.time) //超时机制
|
||
{
|
||
BFLog.LogError("[ResMgr] bundlepath : {0}, timeout ! assetbunle is null = {1}", AssetPath, (null == Assetbundle));
|
||
Timeout += ResourceManager.TIME_OUT_LOAD;
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
else if (EAssetLoadStatus.Complete == LoadStatus)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
catch (Exception ex) //需要测试!!!! 尝试捕获异常,保证单个资源加载出错不卡住游戏。比如异步过程中被同步调用等。
|
||
{
|
||
BFLog.LogError("[ResMgr] loading exception! assetpath : {0}, exception : {1}", AssetPath, ex.ToString());
|
||
return true;
|
||
}
|
||
}
|
||
|
||
public void Complete(AssetBundle ab)
|
||
{
|
||
Assetbundle = ab;
|
||
LoadStatus = ab == null ? EAssetLoadStatus.Error : EAssetLoadStatus.Complete;
|
||
request = null;
|
||
loadComplete.Invoke(this);
|
||
loadComplete.Clear();
|
||
}
|
||
|
||
public void AddUnloadCallback(Action unloadCallback)
|
||
{
|
||
unloadComplete += unloadCallback;
|
||
}
|
||
|
||
public override bool Unload(bool immediately)
|
||
{
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] assetBundleobject base unload assetpath : {0}, refcount : {1}", AssetPath, RefCount);
|
||
if (RefCount == 0)
|
||
return false;
|
||
|
||
--RefCount;
|
||
if (RefCount == 0)
|
||
{
|
||
loadComplete.Clear();
|
||
LoadStatus = EAssetLoadStatus.Unloading;
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] assetobject unloaded immediately");
|
||
UnloadCountdown(true); // assetbundle目前都是立即卸载
|
||
return false;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
protected override bool OnUnloadComplete()
|
||
{
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] AssetBundleObject OnUnloadComplete start LoadStatus : {0}", LoadStatus);
|
||
if (EAssetLoadStatus.Complete == LoadStatus)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (!ReferenceEquals(null, request))
|
||
{
|
||
var assetbundle = request.assetBundle;
|
||
assetbundle.Unload(true);
|
||
request = null;
|
||
}
|
||
|
||
if (!ReferenceEquals(null, Assetbundle))
|
||
{
|
||
Assetbundle.Unload(true);
|
||
Assetbundle = null;
|
||
}
|
||
|
||
LoadStatus = EAssetLoadStatus.Unloaded;
|
||
assetBundleLoader.RemoveCache(this);
|
||
unloadComplete.Invoke();
|
||
unloadComplete.Clear();
|
||
for (int i = 0; i < dependAB.Length; i++)
|
||
{
|
||
assetBundleLoader.UnLoadBundle(dependAB[i], true);
|
||
}
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] OnUnloadComplete end ");
|
||
return true;
|
||
}
|
||
}
|
||
} |