/// <summary> /// 不需要实例化的资源的卸载,根据对象 /// </summary> /// <param name="obj"></param> /// <param name="destoryObj"></param> /// <returns></returns> public bool ReleaseResource(Object obj, bool destoryObj = false) { if (obj == null) { return(false); } ResouceItem item = null; foreach (ResouceItem res in AssetDic.Values) { if (res.m_Guid == obj.GetInstanceID()) { item = res; } } if (item == null) { DebugPlus.LogError("AssetDic里不存在改资源:" + obj.name + " 可能释放了多次"); return(false); } item.RefCount--; DestoryResouceItme(item, destoryObj); return(true); }
/// <summary> /// 针对ObjectManager的异步加载接口 /// </summary> /// <param name="path"></param> /// <param name="resObj"></param> /// <param name="dealfinish"></param> /// <param name="priority"></param> public void AsyncLoadResource(string path, ResouceObj resObj, OnAsyncFinsih dealfinish, LoadResPriority priority) { ResouceItem item = GetCacheResouceItem(resObj.m_Crc); if (item != null) { resObj.m_ResItem = item; if (dealfinish != null) { dealfinish(path, resObj); } return; } //判断是否在加载中 AsyncLoadResParam para = null; if (!m_LoadingAssetDic.TryGetValue(resObj.m_Crc, out para) || para == null) { para = m_AsyncLoadResParamPool.Spawn(true); para.m_Crc = resObj.m_Crc; para.m_Path = path; para.m_Priority = priority; m_LoadingAssetDic.Add(resObj.m_Crc, para); m_LoadingAssetList[(int)priority].Add(para); } //往回调列表里面加回调 AsyncCallBack callBack = m_AsyncCallBackPool.Spawn(true); callBack.m_DealFinish = dealfinish; callBack.m_ResObj = resObj; para.m_CallBackList.Add(callBack); }
/// <summary> /// 回收一个资源 /// </summary> /// <param name="item"></param> /// <param name="destroy"></param> protected void DestoryResouceItme(ResouceItem item, bool destroyCache = false) { if (item == null || item.RefCount > 0) { return; } if (!destroyCache) { m_NoRefrenceAssetMapList.InsertToHead(item); return; } if (!AssetDic.Remove(item.m_Crc)) { return; } m_NoRefrenceAssetMapList.Remove(item); //释放assetbundle引用 AssetBundleManager.Instance.ReleaseAsset(item); //清空资源对应的对象池 ObjectManager.Instance.ClearPoolObject(item.m_Crc); if (item.m_Obj != null) { item.m_Obj = null; #if UNITY_EDITOR Resources.UnloadUnusedAssets(); #endif } }
/// <summary> /// 根据crc朝赵ResouceItem /// </summary> /// <param name="crc"></param> /// <returns></returns> public ResouceItem FindResourceItme(uint crc) { ResouceItem item = null; m_ResouceItemDic.TryGetValue(crc, out item); return(item); }
/// <summary> /// 缓存加载的资源 /// </summary> /// <param name="path"></param> /// <param name="item"></param> /// <param name="crc"></param> /// <param name="obj"></param> /// <param name="addrefcount"></param> void CacheResource(string path, ref ResouceItem item, uint crc, Object obj, int addrefcount = 1) { //缓存太多,清除最早没有使用的资源 WashOut(); if (item == null) { DebugPlus.LogError("ResouceItem is null, path: " + path); } if (obj == null) { DebugPlus.LogError("ResouceLoad Fail : " + path); } item.m_Obj = obj; item.m_Guid = obj.GetInstanceID(); item.m_LastUseTime = Time.realtimeSinceStartup; item.RefCount += addrefcount; ResouceItem oldItme = null; if (AssetDic.TryGetValue(item.m_Crc, out oldItme)) { AssetDic[item.m_Crc] = item; } else { AssetDic.Add(item.m_Crc, item); } }
/// <summary> /// 根据路径的crc加载中间类ResoucItem /// </summary> /// <param name="crc"></param> /// <returns></returns> public ResouceItem LoadResouceAssetBundle(uint crc) { ResouceItem item = null; if (!m_ResouceItemDic.TryGetValue(crc, out item) || item == null) { DebugPlus.LogError(string.Format("LoadResourceAssetBundle error: can not find crc {0} in AssetBundleConfig", crc.ToString())); return(item); } if (item.m_AssetBundle != null) { return(item); } item.m_AssetBundle = LoadAssetBundle(item.m_ABName); if (item.m_DependAssetBundle != null) { for (int i = 0; i < item.m_DependAssetBundle.Count; i++) { LoadAssetBundle(item.m_DependAssetBundle[i]); } } return(item); }
/// <summary> /// 预加载资源 /// </summary> /// <param name="path"></param> public void PreloadRes(string path) { if (string.IsNullOrEmpty(path)) { return; } uint crc = CRC32.GetCrc32(path); ResouceItem item = GetCacheResouceItem(crc, 0); if (item != null) { return; } Object obj = null; #if UNITY_EDITOR if (!m_LoadFormAssetBundle) { item = AssetBundleManager.Instance.FindResourceItme(crc); if (item != null && item.m_Obj != null) { obj = item.m_Obj as Object; } else { if (item == null) { item = new ResouceItem(); item.m_Crc = crc; } obj = LoadAssetByEditor <Object>(path); } } #endif if (obj == null) { item = AssetBundleManager.Instance.LoadResouceAssetBundle(crc); if (item != null && item.m_AssetBundle != null) { if (item.m_Obj != null) { obj = item.m_Obj; } else { obj = item.m_AssetBundle.LoadAsset <Object>(item.m_AssetName); } } } CacheResource(path, ref item, crc, obj); //跳场景不清空缓存 item.m_Clear = false; ReleaseResource(obj, false); }
public void Reset() { m_Crc = 0; m_CloneObj = null; m_bClear = true; m_Guid = 0; m_ResItem = null; m_Already = false; m_SetSceneParent = false; m_DealFinish = null; m_Param1 = m_Param2 = m_Param3 = null; }
/// <summary> /// 缓存太多,清除最早没有使用的资源 /// </summary> protected void WashOut() { //当大于缓存个数时,进行一半释放 while (m_NoRefrenceAssetMapList.Size() >= MAXCACHECOUNT) { for (int i = 0; i < MAXCACHECOUNT / 2; i++) { ResouceItem item = m_NoRefrenceAssetMapList.Back(); DestoryResouceItme(item, true); } } }
/// <summary> /// 根据路径减少引用计数 /// </summary> /// <param name="crc"></param> /// <param name="count"></param> /// <returns></returns> public int DecreaseResoucerRef(uint crc, int count = 1) { ResouceItem item = null; if (!AssetDic.TryGetValue(crc, out item) || item == null) { return(0); } item.RefCount -= count; return(item.RefCount); }
/// <summary> /// 根据path增加引用计数 /// </summary> /// <param name="crc"></param> /// <param name="count"></param> /// <returns></returns> public int IncreaseResouceRef(uint crc = 0, int count = 1) { ResouceItem item = null; if (!AssetDic.TryGetValue(crc, out item) || item == null) { return(0); } item.RefCount += count; item.m_LastUseTime = Time.realtimeSinceStartup; return(item.RefCount); }
/// <summary> /// 从资源池获取缓存资源 /// </summary> /// <param name="crc"></param> /// <param name="addrefcount"></param> /// <returns></returns> ResouceItem GetCacheResouceItem(uint crc, int addrefcount = 1) { ResouceItem item = null; if (AssetDic.TryGetValue(crc, out item)) { if (item != null) { item.RefCount += addrefcount; item.m_LastUseTime = Time.realtimeSinceStartup; } } return(item); }
/// <summary> /// 释放资源 /// </summary> /// <param name="item"></param> public void ReleaseAsset(ResouceItem item) { if (item == null) { return; } if (item.m_DependAssetBundle != null && item.m_DependAssetBundle.Count > 0) { for (int i = 0; i < item.m_DependAssetBundle.Count; i++) { UnLoadAssetBundle(item.m_DependAssetBundle[i]); } } UnLoadAssetBundle(item.m_ABName); }
/// <summary> /// 加载ab配置表 /// </summary> /// <returns></returns> public bool LoadAssetBundleConfig() { #if UNITY_EDITOR if (!ResourceManager.m_LoadFormAssetBundle) { return(false); } #endif m_ResouceItemDic.Clear(); AssetBundle configAB = null; configAB = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/assetbundleconfig"); //configAB = AssetBundle.LoadFromFile(ABLoadPath + "assetbundleconfig"); TextAsset textAsset = configAB.LoadAsset <TextAsset>(m_ABConfigABName); if (textAsset == null) { DebugPlus.LogError("AssetBundleConfig is no exist!"); return(false); } MemoryStream stream = new MemoryStream(textAsset.bytes); BinaryFormatter bf = new BinaryFormatter(); AssetBundleConfig config = (AssetBundleConfig)bf.Deserialize(stream); stream.Close(); for (int i = 0; i < config.ABList.Count; i++) { ABBase abBase = config.ABList[i]; ResouceItem item = new ResouceItem(); item.m_Crc = abBase.Crc; item.m_AssetName = abBase.AssetName; item.m_ABName = abBase.ABName; item.m_DependAssetBundle = abBase.ABDependce; if (m_ResouceItemDic.ContainsKey(item.m_Crc)) { DebugPlus.LogError("重复的Crc 资源名:" + item.m_AssetName + " ab包名:" + item.m_ABName); } else { m_ResouceItemDic.Add(item.m_Crc, item); } } return(true); }
/// <summary> /// 不需要实例化的资源卸载,根据路径 /// </summary> /// <param name="path"></param> /// <param name="destoryObj"></param> /// <returns></returns> public bool ReleaseResource(string path, bool destoryObj = false) { if (string.IsNullOrEmpty(path)) { return(false); } uint crc = CRC32.GetCrc32(path); ResouceItem item = null; if (!AssetDic.TryGetValue(crc, out item) || null == item) { DebugPlus.LogError("AssetDic里不存在改资源:" + path + " 可能释放了多次"); } item.RefCount--; DestoryResouceItme(item, destoryObj); return(true); }
/// <summary> /// 异步加载资源(仅仅是不需要实例化的资源,例如音频,图片等等) /// </summary> public void AsyncLoadResource(string path, OnAsyncObjFinish dealFinish, LoadResPriority priority, bool isSprite = false, object param1 = null, object param2 = null, object param3 = null, uint crc = 0) { if (crc == 0) { crc = CRC32.GetCrc32(path); } ResouceItem item = GetCacheResouceItem(crc); if (item != null) { if (dealFinish != null) { dealFinish(path, item.m_Obj, param1, param2, param3); } return; } //判断是否在加载中 AsyncLoadResParam para = null; if (!m_LoadingAssetDic.TryGetValue(crc, out para) || para == null) { para = m_AsyncLoadResParamPool.Spawn(true); para.m_Crc = crc; para.m_Path = path; para.m_Sprite = isSprite; para.m_Priority = priority; m_LoadingAssetDic.Add(crc, para); m_LoadingAssetList[(int)priority].Add(para); } //往回调列表里面加回调 AsyncCallBack callBack = m_AsyncCallBackPool.Spawn(true); callBack.m_DealObjFinish = dealFinish; callBack.m_Param1 = param1; callBack.m_Param2 = param2; callBack.m_Param3 = param3; para.m_CallBackList.Add(callBack); }
/// <summary> /// 根据ResouceObj卸载资源 /// </summary> /// <param name="resObj"></param> /// <param name="destoryObj"></param> /// <returns></returns> public bool ReleaseResource(ResouceObj resObj, bool destoryObj = false) { if (resObj == null) { return(false); } ResouceItem item = null; if (!AssetDic.TryGetValue(resObj.m_Crc, out item) || null == item) { DebugPlus.LogError("AssetDic里不存在改资源:" + resObj.m_CloneObj.name + " 可能释放了多次"); } GameObject.Destroy(resObj.m_CloneObj); item.RefCount--; DestoryResouceItme(item, destoryObj); return(true); }
/// <summary> /// 同步加载资源,针对给ObjectManager的接口 /// </summary> /// <param name="path"></param> /// <param name="resObj"></param> /// <returns></returns> public ResouceObj LoadResource(string path, ResouceObj resObj) { if (resObj == null) { return(null); } uint crc = resObj.m_Crc == 0 ? CRC32.GetCrc32(path) : resObj.m_Crc; ResouceItem item = GetCacheResouceItem(crc); if (item != null) { resObj.m_ResItem = item; return(resObj); } Object obj = null; #if UNITY_EDITOR if (!m_LoadFormAssetBundle) { item = AssetBundleManager.Instance.FindResourceItme(crc); if (item != null && item.m_Obj != null) { obj = item.m_Obj as Object; } else { if (item == null) { item = new ResouceItem(); item.m_Crc = crc; } obj = LoadAssetByEditor <Object>(path); } } #endif if (obj == null) { item = AssetBundleManager.Instance.LoadResouceAssetBundle(crc); if (item != null && item.m_AssetBundle != null) { if (item.m_Obj != null) { obj = item.m_Obj as Object; } else { obj = item.m_AssetBundle.LoadAsset <Object>(item.m_AssetName); } } } CacheResource(path, ref item, crc, obj); resObj.m_ResItem = item; item.m_Clear = resObj.m_bClear; return(resObj); }
/// <summary> /// 异步加载 /// </summary> /// <returns></returns> IEnumerator AsyncLoadCor() { List <AsyncCallBack> callBackList = null; //上一次yield的视角 long lastYiledTime = System.DateTime.Now.Ticks; while (true) { bool haveYield = false; for (int i = 0; i < (int)LoadResPriority.RES_NUM; i++) { if (m_LoadingAssetList[(int)LoadResPriority.RES_HIGHT].Count > 0) { i = (int)LoadResPriority.RES_HIGHT; } else if (m_LoadingAssetList[(int)LoadResPriority.RES_MIDDLE].Count > 0) { i = (int)LoadResPriority.RES_MIDDLE; } List <AsyncLoadResParam> loadingList = m_LoadingAssetList[i]; if (loadingList.Count <= 0) { continue; } AsyncLoadResParam loadingItem = loadingList[0]; loadingList.RemoveAt(0); callBackList = loadingItem.m_CallBackList; Object obj = null; ResouceItem item = null; #if UNITY_EDITOR if (!m_LoadFormAssetBundle) { if (loadingItem.m_Sprite) { obj = LoadAssetByEditor <Sprite>(loadingItem.m_Path); } else { obj = LoadAssetByEditor <Object>(loadingItem.m_Path); } //模拟异步加载 yield return(new WaitForEndOfFrame()); item = AssetBundleManager.Instance.FindResourceItme(loadingItem.m_Crc); if (item == null) { item = new ResouceItem(); item.m_Crc = loadingItem.m_Crc; } } #endif if (obj == null) { item = AssetBundleManager.Instance.LoadResouceAssetBundle(loadingItem.m_Crc); if (item != null && item.m_AssetBundle != null) { AssetBundleRequest abRequest = null; if (loadingItem.m_Sprite) { abRequest = item.m_AssetBundle.LoadAssetAsync <Sprite>(item.m_AssetName); } else { abRequest = item.m_AssetBundle.LoadAssetAsync(item.m_AssetName); } yield return(abRequest); if (abRequest.isDone) { obj = abRequest.asset; } lastYiledTime = System.DateTime.Now.Ticks; } } CacheResource(loadingItem.m_Path, ref item, loadingItem.m_Crc, obj, callBackList.Count); for (int j = 0; j < callBackList.Count; j++) { AsyncCallBack callBack = callBackList[j]; if (callBack != null && callBack.m_DealFinish != null && callBack.m_ResObj != null) { ResouceObj tempResObj = callBack.m_ResObj; tempResObj.m_ResItem = item; callBack.m_DealFinish(loadingItem.m_Path, tempResObj, tempResObj.m_Param1, tempResObj.m_Param2, tempResObj.m_Param3); callBack.m_DealFinish = null; tempResObj = null; } if (callBack != null && callBack.m_DealObjFinish != null) { callBack.m_DealObjFinish(loadingItem.m_Path, obj, callBack.m_Param1, callBack.m_Param2, callBack.m_Param3); callBack.m_DealObjFinish = null; } callBack.Reset(); m_AsyncCallBackPool.Recycle(callBack); } obj = null; callBackList.Clear(); m_LoadingAssetDic.Remove(loadingItem.m_Crc); loadingItem.Reset(); m_AsyncLoadResParamPool.Recycle(loadingItem); if (System.DateTime.Now.Ticks - lastYiledTime > MAXLOADRESTIME) { yield return(null); lastYiledTime = System.DateTime.Now.Ticks; haveYield = true; } } if (!haveYield || System.DateTime.Now.Ticks - lastYiledTime > MAXLOADRESTIME) { lastYiledTime = System.DateTime.Now.Ticks; yield return(null); } } }
/// <summary> /// 同步资源加载,外部直接调用,仅加载不需要实例化的资源,例如Texture,音频等等 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="path"></param> /// <returns></returns> public T LoadResource <T>(string path) where T : UnityEngine.Object { if (string.IsNullOrEmpty(path)) { return(null); } uint crc = CRC32.GetCrc32(path); ResouceItem item = GetCacheResouceItem(crc); if (item != null) { return(item.m_Obj as T); } T obj = null; #if UNITY_EDITOR if (!m_LoadFormAssetBundle) { item = AssetBundleManager.Instance.FindResourceItme(crc); if (item != null && item.m_AssetBundle != null) { if (item.m_Obj != null) { obj = (T)item.m_Obj; } else { obj = item.m_AssetBundle.LoadAsset <T>(item.m_AssetName); } } else { if (item == null) { item = new ResouceItem(); item.m_Crc = crc; } obj = LoadAssetByEditor <T>(path); } } #endif if (obj == null) { item = AssetBundleManager.Instance.LoadResouceAssetBundle(crc); if (item != null && item.m_AssetBundle != null) { if (item.m_Obj != null) { obj = item.m_Obj as T; } else { obj = item.m_AssetBundle.LoadAsset <T>(item.m_AssetName); } } } CacheResource(path, ref item, crc, obj); return(obj); }