243 lines
8.0 KiB
C#
243 lines
8.0 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using UnityEngine;
|
||
using UEObject = UnityEngine.Object;
|
||
|
||
namespace BF
|
||
{
|
||
public class ResourceManager : ManagerBase
|
||
{
|
||
static ResourceManager instance;
|
||
public static ResourceManager Create()
|
||
{
|
||
BFLog.LogAssert(instance == null, "This method only allows BFMain to call once");
|
||
instance = new ResourceManager();
|
||
return instance;
|
||
}
|
||
|
||
// 单个资源加载时间消耗上限.单位 s unity内部的ab加载可能也做了队列,超时先设高点,避免同时加载多个容易超时
|
||
public const float TIME_OUT_LOAD = 30f;
|
||
|
||
// 资源卸载延迟时间
|
||
public const float TIME_DELAY_UNLOAD = 2f;
|
||
|
||
public AssetBundleConfigCollection AbConfigCollection { get; private set; }
|
||
public AssetBundleManifest Manifest { get; private set; }
|
||
|
||
public override void Destroy()
|
||
{
|
||
instance = null;
|
||
}
|
||
|
||
public void Clear()
|
||
{
|
||
var assetList = assets.Values.ToList();
|
||
var count = assetList.Count;
|
||
for (int i = count - 1; i >= 0; i--)
|
||
{
|
||
while (assetList[i].RefCount > 0)
|
||
{
|
||
Unload(assetList[i].AssetPath, true);
|
||
}
|
||
}
|
||
assets.Clear();
|
||
AssetBundleObject.fullpathDict.Clear();
|
||
loader.Clear();
|
||
}
|
||
|
||
//资源缓存
|
||
private Dictionary<string, AssetObject> assets = new Dictionary<string, AssetObject>();
|
||
|
||
private LoaderBase loader;
|
||
|
||
private ResourceManager() { }
|
||
|
||
public override void Init()
|
||
{
|
||
#if UNITY_EDITOR
|
||
#if USE_AB
|
||
loader = new AssetBundleLoader();
|
||
#else
|
||
loader = new AssetLoader();
|
||
#endif
|
||
#else
|
||
loader = new AssetBundleLoader();
|
||
#endif
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置资源配置
|
||
/// </summary>
|
||
public void SetAbConfigCollection(AssetBundleConfigCollection abcc)
|
||
{
|
||
AbConfigCollection = abcc;
|
||
AssetBundleObject.fullpathDict.Clear();
|
||
}
|
||
|
||
public void ReloadManifest()
|
||
{
|
||
#if USE_AB
|
||
if (Manifest != null)
|
||
{
|
||
Resources.UnloadAsset(Manifest);
|
||
Manifest = null;
|
||
}
|
||
|
||
var persistentPath = System.IO.Path.Combine(Application.persistentDataPath, "update", "asset_bundle_manifest.ab");
|
||
AssetBundle assetBundle;
|
||
if (System.IO.File.Exists(persistentPath))
|
||
{
|
||
BFLog.Log("加载manifest " + persistentPath);
|
||
assetBundle = AssetBundle.LoadFromFile(persistentPath);
|
||
}
|
||
else
|
||
{
|
||
var streamPath = System.IO.Path.Combine(Application.streamingAssetsPath, "asset_bundle_manifest.ab");
|
||
BFLog.Log("加载manifest " + streamPath);
|
||
assetBundle = AssetBundle.LoadFromFile(streamPath);
|
||
if (assetBundle == null)
|
||
{
|
||
BFLog.LogError("assetbundlemainfest is null! persistentpath : {0}, streamPath : {1}", persistentPath, streamPath);
|
||
return;
|
||
}
|
||
}
|
||
|
||
Manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
|
||
assetBundle.Unload(false);
|
||
#endif
|
||
}
|
||
|
||
public uint LoadAsync(string assetPath, Type type, Action<string, UnityEngine.Object> complete)
|
||
{
|
||
if (string.IsNullOrEmpty(assetPath) || type == null || complete == null)
|
||
{
|
||
return 0;
|
||
}
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] LoadAsync : {0}, type : {1}", assetPath, type.ToString());
|
||
if (assets.TryGetValue(assetPath, out AssetObject assetObj))
|
||
{
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] LoadAsync : {0}, type : {1}. Already Complete!", assetPath, type.ToString());
|
||
if (EAssetLoadStatus.Unloading == assetObj.LoadStatus)
|
||
{
|
||
assetObj.LoadStatus = EAssetLoadStatus.Complete;
|
||
}
|
||
else if (EAssetLoadStatus.Error == assetObj.LoadStatus) //出错的资源,尝试重新加载
|
||
{
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] assetpath : {0} 上次加载出错了,重新加载", assetPath);
|
||
loader.LoadAssetAsync(assetObj);
|
||
}
|
||
assetObj.LoadAsync(complete);
|
||
}
|
||
else
|
||
{
|
||
assetObj = loader.LoadAssetAsync(assetPath, type, complete);
|
||
assets.Add(assetPath, assetObj);
|
||
assetObj.LoadAsync(complete);
|
||
}
|
||
return assetObj.Id;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 此接口需要多测试!!!尝试unity2018的api。可以直接从异步接口中返回同步值,从而从把异步变成同步
|
||
/// </summary>
|
||
/// <param name="assetPath"></param>
|
||
/// <param name="type"></param>
|
||
/// <returns></returns>
|
||
public UEObject LoadSync(string assetPath, Type type)
|
||
{
|
||
if (string.IsNullOrEmpty(assetPath) || type == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
if (assets.TryGetValue(assetPath, out AssetObject assetObj))
|
||
{
|
||
if (EAssetLoadStatus.Error == assetObj.LoadStatus) //出错的资源,尝试重新加载
|
||
{
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] assetpath : {0} 上次加载出错了,重新加载", assetPath);
|
||
loader.LoadAssetSync(assetObj);
|
||
}
|
||
else if (EAssetLoadStatus.Wait == assetObj.LoadStatus)
|
||
{
|
||
loader.LoadAssetSync(assetObj);
|
||
}
|
||
assetObj.LoadSync();
|
||
}
|
||
else
|
||
{
|
||
assetObj = loader.LoadAssetSync(assetPath, type);
|
||
assetObj.LoadSync();
|
||
assets.Add(assetPath, assetObj);
|
||
}
|
||
return assetObj.Asset;
|
||
}
|
||
|
||
public void Unload(string assetPath, bool immediately)
|
||
{
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] Unload assetpath : {0}", assetPath);
|
||
if (string.IsNullOrEmpty(assetPath))
|
||
{
|
||
return;
|
||
}
|
||
if (!assets.TryGetValue(assetPath, out AssetObject ao))
|
||
{
|
||
return;
|
||
}
|
||
loader.Unload(ao, immediately);
|
||
}
|
||
|
||
public void Unload(AssetObject assetObject, bool immediately)
|
||
{
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] Unload assetObject : {0}", assetObject);
|
||
if (assetObject == null)
|
||
{
|
||
return;
|
||
}
|
||
loader.Unload(assetObject, immediately);
|
||
}
|
||
|
||
public void RemoveAsset(string assetPath)
|
||
{
|
||
BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] RemoveAsset assetPath : {0}", assetPath);
|
||
if (assets.ContainsKey(assetPath))
|
||
{
|
||
assets.Remove(assetPath);
|
||
}
|
||
}
|
||
|
||
public void UnloadAllDelayAssets()
|
||
{
|
||
loader.UnloadAllDelayAssets();
|
||
}
|
||
|
||
public string GetSceneLoadPath(string assetBundlePath)
|
||
{
|
||
return loader.GetSceneLoadPath(assetBundlePath);
|
||
}
|
||
|
||
public void LoadSceneAsync(string assetBundlePath, Action<AssetBundleObject> complete)
|
||
{
|
||
loader.LoadSceneAsync(assetBundlePath, complete);
|
||
}
|
||
|
||
public void UnloadScene(string assetBundlePath)
|
||
{
|
||
loader.UnloadScene(assetBundlePath);
|
||
}
|
||
|
||
public bool ContainsAsset(string assetPath)
|
||
{
|
||
return loader.ContainsAsset(assetPath);
|
||
}
|
||
|
||
public override void Update()
|
||
{
|
||
if (loader != null)
|
||
{
|
||
loader.Tick();
|
||
}
|
||
}
|
||
}
|
||
}
|