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