using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Object = UnityEngine.Object;
using GameCore;
using System.IO;
namespace ResMgr
{
///
/// AB文件加载状态
///
public enum ABLoaderState
{
//等待中
Wait,
//加载中
Loading,
//加载成功
Success,
//加载失败
Failed,
//被卸载掉了
Release
}
///
/// AB文件加载器
///
public class AssetBundleLoader:MonoBehaviour
{
public class ABLoaderEvent : UnityEvent { };
///
/// 路径
///
[SerializeField]
protected string path;
///
/// 用于加载的路径
///
[SerializeField]
protected string fullPath;
///
/// AB文件
///
protected AssetBundle assetBundle;
///
/// 加载完成回调
///
protected ABLoaderEvent onLoadFinish;
///
/// 依赖
///
[SerializeField]
protected List dependences;
///
/// 引用AB包
///
[SerializeField]
protected List refBundles;
///
/// 引用的资源
///
[SerializeField]
protected List refResDatas;
///
/// 是否加载完成
///
protected bool isLoadFinish;
///
/// 进度
///
protected float progress;
///
/// 加载状态
///
[SerializeField]
protected ABLoaderState abLoaderState = ABLoaderState.Wait;
///
/// 优先级,值越大越优先加载
///
[SerializeField]
protected int priority;
///
/// 是否为全局的
///
[SerializeField]
protected bool isGlobal;
///
/// 生命周期剩余
///
[SerializeField]
protected int leftLife;
///
/// ABLoader状态
///
public ABLoaderState AbLoaderState
{
get
{
return abLoaderState;
}
}
///
/// 是否加载完成
///
public bool IsLoadFinish
{
get
{
return isLoadFinish;
}
}
///
/// 完整的加载路径
///
public string FullPath {
get {
return fullPath;
}
}
///
/// 路径
///
public string Path
{
get
{
return path;
}
}
///
/// 是否为全局AB包,全局AB包不会被自动卸载
///
public bool IsGlobal
{
get
{
return isGlobal;
}
set
{
isGlobal = value;
}
}
///
/// 剩余生命周期
///
public int LifeTime
{
get
{
return leftLife;
}
set
{
leftLife = value;
}
}
public float Progress
{
get
{
return progress;
}
}
private void Awake()
{
refBundles = ListPool.Get();
dependences = ListPool.Get();
refResDatas = new List();
onLoadFinish = new ABLoaderEvent();
}
///
/// 初始化
///
/// 加载路径
/// 依赖
public void Init(string path, string fullPath)
{
this.path = path;
this.fullPath = fullPath;
this.abLoaderState = ABLoaderState.Wait;
}
///
/// 添加加载完成回调
///
///
public void AddListener(UnityAction action)
{
if (action == null) return;
this.onLoadFinish.AddListener(action);
}
///
/// 添加依赖项
///
///
public void AddDependence(AssetBundleLoader loader) {
dependences.Add(loader);
}
///
/// 添加AssetBundle对AssetBundle的引用
///
///
public void AddRefBundle(AssetBundleLoader bundleName)
{
refBundles.Add(bundleName);
}
///
///移除AssetBundle对AssetBundle的引用
///
///
public void RemoveRefBundle(AssetBundleLoader bundleName)
{
refBundles.Remove(bundleName);
}
///
/// 添加资源对AssetBundle的引用
///
///
public void AddRefResData(string resName) {
refResDatas.Add(resName);
if(BaseLogger.isDebug) BaseLogger.LogFormat("AddRefResData:{0}--path:->{1}--count:->>{2}", resName, path, refResDatas.Count);
}
///
/// 移除资源对AssetBundle的引用
///
///
public void RemoveRefResData(string resName) {
refResDatas.Remove(resName);
if (BaseLogger.isDebug) BaseLogger.LogFormat("RemoveRefResData:{0}--path:->{1}--count:->{2}", resName, path, refResDatas.Count);
}
///
/// 是否可以被释放掉了
///
public bool IsFree{
get {
return refResDatas.Count == 0 && refBundles.Count == 0;
}
}
///
/// 加载资源
///
///
///
///
public T LoadAsset(string assetName) where T : Object
{
if (BaseLogger.isDebug) BaseLogger.LogFormat("LoadAsset:{0}", assetName);
if (assetBundle != null)
{
#if XNCS
XNCSUtils.BeginSample("LoadAsset:{0}",path);
#endif
T t = assetBundle.LoadAsset(assetName);
#if XNCS
XNCSUtils.EndSample();
#endif
return t;
}
return null;
}
///
/// 异步加载资源
///
///
///
public void LoadAssetAsyn(string assetName, UnityAction action) where T : Object
{
StartCoroutine(_LoadAssetAsyn(assetName,action));
}
///
/// 异步加载资源
///
///
///
///
///
private IEnumerator _LoadAssetAsyn(string assetName,UnityAction action) where T : Object
{
if (BaseLogger.isDebug) BaseLogger.LogFormat("LoadAssetAsyn:{0}", assetName);
if (assetBundle != null)
{
AssetBundleRequest request = assetBundle.LoadAssetAsync(assetName);
yield return request;
if (request != null) {
action(request.asset as T);
yield break;
}
}
action(null);
}
///
/// 加载所有资源
///
public Object[] LoadAllAsset()
{
if (assetBundle != null)
{
#if XNCS
XNCSUtils.BeginSample("LoadAllAsset,Path ={0}",path);
#endif
Object[] objs = assetBundle.LoadAllAssets();
#if XNCS
XNCSUtils.EndSample();
#endif
return objs;
}
return null;
}
///
/// 加载所有资源
///
///
///
public T[] LoadAllAsset() where T : Object
{
if (assetBundle != null)
{
#if XNCS
XNCSUtils.BeginSample("LoadAllAsset:{0}",path);
#endif
T[] ts = assetBundle.LoadAllAssets();
#if XNCS
XNCSUtils.EndSample();
#endif
return ts;
}
return null;
}
///
/// 加载AB文件
///
virtual public bool LoadAssetBundle()
{
if (BaseLogger.isDebug) BaseLogger.LogFormat("LoadAssetBundle:{0}", path);
#if XNCS
XNCSUtils.BeginSample("LoadAssetBundle:{0}",path);
#endif
//assetBundle = AssetBundle.LoadFromMemory(XXTEA.Decrypt(File.ReadAllBytes(fullPath)));
assetBundle = AssetBundle.LoadFromFile(fullPath, 0, GameLogic.AppConst.EncyptBytesLength);
#if XNCS
XNCSUtils.EndSample();
#endif
if (assetBundle != null)
{
LoadOver();
return true;
}
else
{
if (BaseLogger.isDebug)
BaseLogger.LogError("同步加载失败:AssetBundle:" + path);
if(fullPath.Contains(ResConfig.StreamPath))
XDebug.Log.error("StreamingAssets 路径资源丢失,请重新打包包内资源!");
LoadFailed();
return false;
}
}
///
/// 异步加载AB文件
///
///
virtual public IEnumerator LoadAssetBundleAsyn()
{
if (BaseLogger.isDebug) BaseLogger.LogFormat("LoadAssetBundleAsyn:{0}", path);
abLoaderState = ABLoaderState.Loading;
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(fullPath, 0, GameLogic.AppConst.EncyptBytesLength);
//AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(XXTEA.Decrypt(File.ReadAllBytes(fullPath)));
while (!request.isDone)
{
progress = request.progress;
yield return null;
}
if (request.assetBundle != null)
{
assetBundle = request.assetBundle;
LoadOver();
}
else
{
if (BaseLogger.isDebug) BaseLogger.LogErrorFormat("异步加载AB失败!,AssetBundle:", path);
LoadFailed();
}
}
///
/// 加载完成
///
protected void LoadOver()
{
abLoaderState = ABLoaderState.Success;
isLoadFinish = true;
progress = 1f;
onLoadFinish.Invoke(this);
onLoadFinish.RemoveAllListeners();
}
///
/// 加载失败
///
public void LoadFailed()
{
abLoaderState = ABLoaderState.Failed;
isLoadFinish = true;
progress = 1f;
onLoadFinish.Invoke(this);
onLoadFinish.RemoveAllListeners();
}
///
/// 卸载AB文件
///
public void UnLoad(bool isForce)
{
if (BaseLogger.isDebug) BaseLogger.LogFormat("UnLoadAssetBundle:{0}", path);
//移除引用
for (int i = 0; i < dependences.Count; i++) {
dependences[i].RemoveRefBundle(this);
}
if (assetBundle != null) {
#if XNCS
XNCSUtils.BeginSample("UnLoadAssetBundle:{0},IsForce:{1}",path,isForce);
#endif
assetBundle.Unload(isForce);
#if XNCS
XNCSUtils.EndSample();
#endif
}
Release();
}
///
/// 清理方法,回收的时候调用
///
public void Release()
{
StopAllCoroutines();
priority = 0;
progress = 0f;
isLoadFinish = false;
onLoadFinish.RemoveAllListeners();
assetBundle = null;
abLoaderState = ABLoaderState.Release;
dependences.Clear();
refBundles.Clear();
isGlobal = false;
}
}
}