/// <summary> /// 取消异步加载资源 /// </summary> /// <returns></returns> public bool CancleLoad(TResouceObj res) { TAsyncLoadResParam para = null; if (mLoadingAssetDic.TryGetValue(res.Crc, out para) && mLoadingAssetList[(int)para.Priority].Contains(para)) { for (int i = para.CallbackList.Count; i > 0; i--) { TAsyncCallBack tempCallBack = para.CallbackList[i]; if (tempCallBack != null && res == tempCallBack.ResObj) { tempCallBack.Reset(); mAsyncCallBackPool.Recycle(tempCallBack); para.CallbackList.Remove(tempCallBack); } } if (para.CallbackList.Count <= 0) { para.Reset(); mLoadingAssetList[(int)para.Priority].Remove(para); mAsyncLoadResParamPool.Recycle(para); mLoadingAssetDic.Remove(res.Crc); return(true); } } return(false); }
/// <summary> /// 针对ObjectManager异步加载的接口 /// </summary> /// <param name="path"></param> /// <param name="resObj"></param> /// <param name="dealfinish"></param> /// <param name="priority"></param> public void AsyncLoadResouce(string path, TResouceObj resObj, OnAsyncFinish dealfinish, LoadResPriority priority) { TResouceItem item = GetCacheResouceItem(resObj.Crc); if (item != null) { resObj.ResItem = item; dealfinish?.Invoke(path, resObj); } //判断是否在加载中 TAsyncLoadResParam para = null; if (!mLoadingAssetDic.TryGetValue(resObj.Crc, out para) || para == null) { para = mAsyncLoadResParamPool.Allocate(); para.Crc = resObj.Crc; para.Path = path; para.Priority = priority; mLoadingAssetDic.Add(resObj.Crc, para); mLoadingAssetList[(int)priority].Add(para); } //往回调列表里面加回调 TAsyncCallBack callBack = mAsyncCallBackPool.Allocate(); callBack.DealFinish = dealfinish; callBack.ResObj = resObj; para.CallbackList.Add(callBack); }
/// <summary> /// 清空对象池 /// </summary> public void ClearCache() { List <uint> tempList = new List <uint>(); foreach (uint key in mObjectPoolDic.Keys) { List <TResouceObj> st = mObjectPoolDic[key]; for (int i = st.Count - 1; i >= 0; i--) { TResouceObj resObj = st[i]; if (!System.Object.ReferenceEquals(resObj.CloneObj, null) && resObj.Clear) { GameObject.Destroy(resObj.CloneObj); mResouceObjDic.Remove(resObj.CloneObj.GetInstanceID()); resObj.Reset(); mResouceObjPool.Recycle(resObj); st.Remove(resObj); } } if (st.Count <= 0) { tempList.Add(key); } } for (int i = 0; i < tempList.Count; i++) { uint temp = tempList[i]; if (mObjectPoolDic.ContainsKey(temp)) { mObjectPoolDic.Remove(temp); } } tempList.Clear(); }
public void ClearPoolObject(uint crc) { List <TResouceObj> st = null; if (!mObjectPoolDic.TryGetValue(crc, out st) || st == null) { return; } for (int i = st.Count - 1; i >= 0; i--) { TResouceObj resObj = st[i]; if (resObj.Clear) { st.Remove(resObj); int tempID = resObj.CloneObj.GetInstanceID(); GameObject.Destroy(resObj.CloneObj); resObj.Reset(); mResouceObjDic.Remove(tempID); mResouceObjPool.Recycle(resObj); } } if (st.Count <= 0) { mObjectPoolDic.Remove(crc); } }
/// <summary> /// 异步加载 /// </summary> /// <param name="path">路径</param> /// <param name="deaFinish">资源加载完成回调</param> /// <param name="priority">加载优先级</param> /// <param name="setSceneParent">是否设置Parent为SceneTrs</param> /// <param name="param1"></param> /// <param name="param2"></param> /// <param name="param3"></param> /// <param name="bClear">跳场景是否清除</param> public long InstantiateObjectAsync(string path, OnAsyncObjFinish deaFinish, LoadResPriority priority, bool setSceneParent = false, object param1 = null, object param2 = null, object param3 = null, bool bClear = true) { if (string.IsNullOrEmpty(path)) { return(0); } uint crc = CRC32.GetCRC32(path); TResouceObj resObj = GetObjectFromPool(crc); if (resObj != null) { if (setSceneParent) { resObj.CloneObj.transform.SetParent(SceneTrs, false); } deaFinish?.Invoke(path, resObj.CloneObj, param1, param2, param3); return(resObj.Guid); } long guid = ResourcesManager.Instance.CreatGuid(); resObj = mResouceObjPool.Allocate(); resObj.Crc = crc; resObj.SetSceneParent = setSceneParent; resObj.Clear = bClear; resObj.DealFinish = deaFinish; resObj.Param1 = param1; resObj.Param2 = param2; resObj.Param3 = param3; //调用ResouceManager的异步加载接口 ResourcesManager.Instance.AsyncLoadResouce(path, resObj, OnLoadResouceObjFinish, priority); return(guid); }
/// <summary> /// 同步加载 /// </summary> /// <param name="path">路径</param> /// <param name="setSceneObj">是否设置Parent为SceneTrs</param> /// <param name="bClear">跳场景是否清除</param> /// /// <param name="createCall">创建时回调函数</param> /// <returns></returns> public GameObject InstantiateObject(string path, bool setSceneParent = false, bool bClear = true) { uint crc = CRC32.GetCRC32(path); TResouceObj resouceObj = GetObjectFromPool(crc); if (resouceObj == null) { resouceObj = mResouceObjPool.Allocate(); resouceObj.Crc = crc; resouceObj.Clear = bClear; //ResouceManager提供加载方法 resouceObj = ResourcesManager.Instance.LoadResouce(path, resouceObj); if (resouceObj.ResItem.Obj != null) { resouceObj.CloneObj = GameObject.Instantiate(resouceObj.ResItem.Obj) as GameObject; resouceObj.OffData = resouceObj.CloneObj.GetComponent <OfflineData>(); resouceObj.OffData.ResetProp(); } } if (setSceneParent) { resouceObj.CloneObj.transform.SetParent(SceneTrs, false); } int tempID = resouceObj.CloneObj.GetInstanceID(); if (!mResouceObjDic.ContainsKey(tempID)) { mResouceObjDic.Add(tempID, resouceObj); } return(resouceObj.CloneObj); }
/// <summary> /// 从对象池取对象 /// </summary> /// <param name="crc"></param> /// <returns></returns> protected TResouceObj GetObjectFromPool(uint crc) { List <TResouceObj> st = null; if (mObjectPoolDic.TryGetValue(crc, out st) && st != null && st.Count > 0) { ResourcesManager.Instance.IncreaseResouceRef(crc); TResouceObj resObj = st[0]; st.RemoveAt(0); GameObject obj = resObj.CloneObj; if (!ReferenceEquals(obj, null)) { if (!ReferenceEquals(resObj.OffData, null)) { resObj.OffData.ResetProp(); } resObj.Already = false; #if UNITY_EDITOR if (obj.name.EndsWith("(Recycle)")) { obj.name = obj.name.Replace("(Recycle)", ""); } #endif } return(resObj); } return(null); }
/// <summary> /// 同步资源加载,外部直接调用,仅加载不需要实例化的资源,例如Texture,音频等 /// </summary> /// <param name="path"></param> /// <param name="resObj"></param> /// <returns></returns> public TResouceObj LoadResouce(string path, TResouceObj resObj) { if (resObj == null) { return(null); } uint crc = resObj.Crc == 0 ? CRC32.GetCRC32(path) : resObj.Crc; TResouceItem item = GetCacheResouceItem(crc); if (item != null) { resObj.ResItem = item; return(resObj); } Object obj = null; #if UNITY_EDITOR if (!AppConfig.UseAssetBundle) { item = AssetBundleManager.Instance.FindResouceItem(crc); if (item != null && item.Obj != null) { obj = item.Obj as Object; } else { if (item == null) { item = new TResouceItem(); item.Crc = crc; } obj = LoadAssetByEditor <Object>(path); } } #endif if (obj == null) { item = AssetBundleManager.Instance.LoadResouceAssetBundle(crc); if (item != null && item.AssetBundle != null) { if (item.Obj != null) { obj = item.Obj as Object; } else { obj = item.AssetBundle.LoadAsset <Object>(item.AssetName); } } } CacheResouce(path, ref item, crc, obj); resObj.ResItem = item; item.Clear = resObj.Clear; return(resObj); }
/// <summary> /// 取消异步加载 /// </summary> /// <param name="guid"></param> public void CancleLoad(long guid) { TResouceObj resObj = null; if (mAsyncResObjs.TryGetValue(guid, out resObj) && ResourcesManager.Instance.CancleLoad(resObj)) { mAsyncResObjs.Remove(guid); resObj.Reset(); mResouceObjPool.Recycle(resObj); } }
/// <summary> /// 根据实例化对象直接获取离线数据 /// </summary> /// <param name="obj">GameObject</param> /// <returns></returns> public OfflineData FindOfflineData(GameObject obj) { OfflineData data = null; TResouceObj resObj = null; mResouceObjDic.TryGetValue(obj.GetInstanceID(), out resObj); if (resObj != null) { data = resObj.OffData; } return(data); }
/// <summary> /// 根据ResouceObj卸载资源 /// </summary> /// <param name="resObj"></param> /// <param name="destroyObj">是否将ResouceItem从缓存引用计数的资源列表中移除</param> /// <returns></returns> public bool ReleaseResouce(TResouceObj resObj, bool destroyObj = false) { if (resObj == null) { return(false); } TResouceItem item = null; if (!mAssetDic.TryGetValue(resObj.Crc, out item) || item == null) { Debug.LogError("AssetDic里不存在该资源:" + resObj.CloneObj.name + " 可能释放了多次"); } GameObject.Destroy(resObj.CloneObj); item.RefCount--; DestroyResouceItem(item, destroyObj); return(true); }
/// <summary> /// 资源加载完成回调 /// </summary> /// <param name="path">路径</param> /// <param name="resObj">中间类</param> /// <param name="param1">参数1</param> /// <param name="param2">参数2</param> /// <param name="param3">参数3</param> void OnLoadResouceObjFinish(string path, TResouceObj resObj, object param1 = null, object param2 = null, object param3 = null) { if (resObj == null) { return; } if (resObj.ResItem.Obj == null) { #if UNITY_EDITOR Debug.LogError("异步资源加载的资源为空:" + path); #endif } else { resObj.CloneObj = GameObject.Instantiate(resObj.ResItem.Obj) as GameObject; resObj.OffData = resObj.CloneObj.GetComponent <OfflineData>(); } //加载完成就从正在加载的异步中移除 if (mAsyncResObjs.ContainsKey(resObj.Guid)) { mAsyncResObjs.Remove(resObj.Guid); } if (resObj.CloneObj != null && resObj.SetSceneParent) { resObj.CloneObj.transform.SetParent(SceneTrs, false); } if (resObj.DealFinish != null) { int tempID = resObj.CloneObj.GetInstanceID(); if (!mResouceObjDic.ContainsKey(tempID)) { mResouceObjDic.Add(tempID, resObj); } //else //{ // resouceObjDic[tempID] = resObj; //} resObj.DealFinish(path, resObj.CloneObj, resObj.Param1, resObj.Param2, resObj.Param3); } }
/// <summary> /// 异步加载 /// </summary> /// <returns></returns> IEnumerator AsyncLoadCor() { List <TAsyncCallBack> callBackList = null; //上一次yild的时间 long lastYildTime = System.DateTime.Now.Ticks; while (true) { bool haveYield = false; for (int i = 0; i < (int)LoadResPriority.RES_NUM; i++) { if (mLoadingAssetList[(int)LoadResPriority.RES_HIGHT].Count > 0) { i = (int)LoadResPriority.RES_HIGHT; } else if (mLoadingAssetList[(int)LoadResPriority.RES_MIDDLE].Count > 0) { i = (int)LoadResPriority.RES_MIDDLE; } List <TAsyncLoadResParam> loadingList = mLoadingAssetList[i]; if (loadingList.Count <= 0) { continue; } TAsyncLoadResParam loadingItem = loadingList[0]; loadingList.RemoveAt(0); callBackList = loadingItem.CallbackList; Object obj = null; TResouceItem item = null; #if UNITY_EDITOR if (!AppConfig.UseAssetBundle) { if (loadingItem.IsSprite) { obj = LoadAssetByEditor <Sprite>(loadingItem.Path); } else { obj = LoadAssetByEditor <Object>(loadingItem.Path); } //模拟异步加载 yield return(new WaitForSeconds(0.5f)); item = AssetBundleManager.Instance.FindResouceItem(loadingItem.Crc); if (item == null) { item = new TResouceItem(); item.Crc = loadingItem.Crc; } } #endif if (obj == null) { item = AssetBundleManager.Instance.LoadResouceAssetBundle(loadingItem.Crc); if (item != null && item.AssetBundle != null) { AssetBundleRequest abRequest = null; if (loadingItem.IsSprite) { abRequest = item.AssetBundle.LoadAssetAsync <Sprite>(item.AssetName); } else { abRequest = item.AssetBundle.LoadAssetAsync(item.AssetName); } yield return(abRequest); if (abRequest.isDone) { obj = abRequest.asset; } lastYildTime = System.DateTime.Now.Ticks; } } CacheResouce(loadingItem.Path, ref item, loadingItem.Crc, obj, callBackList.Count); for (int j = 0; j < callBackList.Count; j++) { TAsyncCallBack callBack = callBackList[j]; if (callBack != null && callBack.DealFinish != null && callBack.ResObj != null) { TResouceObj tempResObj = callBack.ResObj; tempResObj.ResItem = item; callBack.DealFinish(loadingItem.Path, tempResObj, tempResObj.Param1, tempResObj.Param2, tempResObj.Param3); callBack.DealFinish = null; tempResObj = null; } if (callBack != null && callBack.DealObjFinish != null) { callBack.DealObjFinish(loadingItem.Path, obj, callBack.Param1, callBack.Param2, callBack.Param3); callBack.DealObjFinish = null; } callBack.Reset(); mAsyncCallBackPool.Recycle(callBack); } obj = null; callBackList.Clear(); mLoadingAssetDic.Remove(loadingItem.Crc); loadingItem.Reset(); mAsyncLoadResParamPool.Recycle(loadingItem); if (System.DateTime.Now.Ticks - lastYildTime > MAXLOADRESTIME) { yield return(null); lastYildTime = System.DateTime.Now.Ticks; haveYield = true; } } if (!haveYield || System.DateTime.Now.Ticks - lastYildTime > MAXLOADRESTIME) { lastYildTime = System.DateTime.Now.Ticks; yield return(null); } yield return(null); } }
/// <summary> /// 根据ResouceObj减少引用计数 /// </summary> /// <param name="resObj"></param> /// <param name="count"></param> /// <returns></returns> public int DecreaseResouceRef(TResouceObj resObj, int count = 0) { return(resObj != null?DecreaseResouceRef(resObj.Crc, count) : 0); }
/// <summary> /// 根据ResObj增加引用计数 /// </summary> /// <param name="resObj"></param> /// <param name="count"></param> /// <returns></returns> public int IncreaseResouceRef(TResouceObj resObj, int count = 1) { return(resObj != null?IncreaseResouceRef(resObj.Crc, count) : 0); }
/// <summary> /// 回收资源 /// </summary> /// <param name="obj"></param> /// <param name="maxCacheCount">最大的缓存数量,负数不限缓存数量,0代表不缓存</param> /// <param name="destroyCache">是否将ResouceItem从缓存引用计数的资源列表中移除</param> /// <param name="recycleParent">是否设置Parent为RecyclePoolTrs</param> public void ReleaseObject(GameObject obj, int maxCacheCount = -1, bool destroyCache = false, bool recycleParent = true) { if (obj == null) { return; } TResouceObj resObj = null; int tempID = obj.GetInstanceID(); if (!mResouceObjDic.TryGetValue(tempID, out resObj)) { Debug.LogError(obj.name + "对象不是ObjectManager创建的!"); return; } if (resObj == null) { Debug.LogError("缓存的ResouceObj为空"); return; } if (resObj.Already) { Debug.LogError("该对象已经放回对象池了,检测自己是否清空引用"); return; } #if UNITY_EDITOR obj.name += "(Recycle)"; #endif List <TResouceObj> st = null; if (maxCacheCount == 0) { mResouceObjDic.Remove(tempID); ResourcesManager.Instance.ReleaseResouce(resObj, destroyCache); resObj.Reset(); mResouceObjPool.Recycle(resObj); } else //回收到对象池 { if (!mObjectPoolDic.TryGetValue(resObj.Crc, out st) || st == null) { st = new List <TResouceObj>(); mObjectPoolDic.Add(resObj.Crc, st); } if (resObj.CloneObj) { if (recycleParent) { resObj.CloneObj.transform.SetParent(RecyclePoolTrs); } else { resObj.CloneObj.SetActive(false); } } if (maxCacheCount < 0 || st.Count < maxCacheCount) { st.Add(resObj); resObj.Already = true; ResourcesManager.Instance.DecreaseResouceRef(resObj); } else { mResouceObjDic.Remove(tempID); ResourcesManager.Instance.ReleaseResouce(resObj, destroyCache); resObj.Reset(); mResouceObjPool.Recycle(resObj); } } }