2023-04-03 11:04:31 +08:00

243 lines
8.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
}
}
}