/// <summary> /// 回收资源 /// </summary> /// <param UIName="obj"></param> /// <param UIName="maxCacheCount"></param> /// <param UIName="destoryCache"></param> /// <param UIName="recycleParent"></param> internal void ReleaseObjectAsset(GameObject obj, int assetHelpHash, bool destoryCache, bool recycleParent, bool clearChangeScene, int maxCacheCount) { if (obj == null) { return; } ResouceObj resObj = null; int tempID = obj.GetInstanceID(); if (!_ResourceObjDic.TryGetValue(tempID, out resObj)) { Debug.Log("这个对象不是ObjectManager创建"); return; } if (resObj == null) { Debug.LogError("缓存的ResourceObj为空"); } if (resObj.AlreadyRelease) { Debug.LogError("该对象已经被释放到对象池,检查是否清空引用"); return; } #if UNITY_EDITOR obj.name += "(Recycle)"; #endif ResManager.Instance.RemoveObjAsset(resObj.Crc, assetHelpHash); ReleaseObject(resObj, tempID, destoryCache, recycleParent, clearChangeScene, maxCacheCount); }
public void Reset() { OnObjFinish = null; OnFinish = null; Params.Clear(); ResObj = null; }
/// <summary> /// 获得对象Crc /// </summary> /// <param name="obj"></param> /// <returns></returns> private uint GetReleseCrc(GameObject obj) { if (obj == null) { return(0); } ResouceObj resObj = null; int tempID = obj.GetInstanceID(); if (!_ResourceObjDic.TryGetValue(tempID, out resObj)) { Debug.Log("这个对象不是ObjectManager创建"); return(0); } if (resObj == null) { Debug.LogError("缓存的ResourceObj为空"); return(0); } else { return(resObj.Crc); } }
/// <summary> /// 清除某个资源在对象池中的所有对象 /// </summary> /// <param UIName="crc"></param> internal void ClearPoolObject(uint crc) { List <ResouceObj> st = null; if (!_ObjectPoolDic.TryGetValue(crc, out st) || st == null) { return; } for (int i = st.Count - 1; i >= 0; i--) { ResouceObj resObj = st[i]; if (resObj.ClearByChangeScene) { st.Remove(resObj); int tempID = resObj.CloneObj.GetInstanceID(); GameObject.Destroy(resObj.CloneObj); _ResourceObjDic.Remove(tempID); //_ResourceObjClassPool.Recycle(resObj); } } if (st.Count <= 0) { _ObjectPoolDic.Remove(crc); } }
/// <summary> /// 从对象池中取对象 /// </summary> /// <param UIName="crc"></param> /// <returns></returns> private ResouceObj GetObjectFromPool(uint crc) { List <ResouceObj> st = null; if (_ObjectPoolDic.TryGetValue(crc, out st) && st != null && st.Count > 0) { ResouceObj resObj = st[0]; st.RemoveAt(0); GameObject obj = resObj.CloneObj; if (!System.Object.ReferenceEquals(obj, null)) { resObj.AlreadyRelease = false; //编辑器下改名 #if UNITY_EDITOR if (!obj) { string error = string.Format("该对象InstanceID[{0}]已经被销毁且没有通过对象池销毁 请检测", resObj.ResItem.Guid); throw new Exception(error); } if (obj.name.EndsWith("(Recycle)")) { obj.name = obj.name.Replace("(Recycle)", ""); } #endif } return(resObj); } return(null); }
/// <summary> /// 根据ResourceObj 卸载资源 /// </summary> /// <param UIName="resObj"></param> /// <param UIName="destroyOjb"></param> /// <returns></returns> internal bool ReleaseResourceAsset(ResouceObj resObj, int assetHelpHash, int poolCacheCount, bool destroyOjb = false) { if (resObj == null) { return(false); } ResItem item = null; if (!_UsededResCacheDic.TryGetValue(resObj.Crc, out item) || item == null) { Debug.LogError("不存在该资源 anme: " + resObj.CloneObj.name + " 可能多次释放"); return(false); } RemoveObjAsset(item.Crc, assetHelpHash); GameObject.Destroy(resObj.CloneObj); if (poolCacheCount == 0 && resObj.ResItem.RefCount.count == 1) { resObj.ResItem.RefCount.Decrease(); DestroyResourceItem(item, destroyOjb); } return(true); }
/// <summary> /// 取消异步加载资源 /// </summary> /// <returns></returns> internal bool CancleLoad(ResouceObj res) { AsyncLoadResParam para = null; if (_LoadingAssetDic.TryGetValue(res.Crc, out para) && _LoadingAssetList[(int)para.Priority].Contains(para)) { for (int i = para.CallBackList.Count - 1; i >= 0; i--) { AsyncCallBack tempCallBack = para.CallBackList[i]; if (tempCallBack != null && res == tempCallBack.ResObj) { para.CallBackList.Remove(tempCallBack); tempCallBack.Reset(); _AsyncCallBackPool.Recycle(tempCallBack); } } if (para.CallBackList.Count <= 0) { _LoadingAssetList[(int)para.Priority].Remove(para); para.Reset(); _AsyncLoadResParamPool.Recycle(para); _LoadingAssetDic.Remove(res.Crc); return(true); } } return(false); }
/// <summary> /// 回收资源 /// </summary> /// <param UIName="obj"></param> /// <param UIName="maxCacheCount"></param> /// <param UIName="destoryCache"></param> /// <param UIName="recycleParent"></param> private void ReleaseObject(ResouceObj resObj, int InstanceID, bool destoryCache, bool recycleParent, bool clearChangeScene, int maxCacheCount) { List <ResouceObj> st = null; //引用计数减一 resObj.ResItem.RefCount.Decrease(); resObj.ClearByChangeScene = clearChangeScene; if (maxCacheCount == 0) { _ObjectPoolDic.TryGetValue(resObj.Crc, out st); _ResourceObjDic.Remove(InstanceID); int poolCount = 0; if (st != null) { poolCount = st.Count; } ResManager.Instance.ReleaseResource(resObj, poolCount, destoryCache); //_ResourceObjClassPool.Recycle(resObj); } else { //回收到对象池 if (!_ObjectPoolDic.TryGetValue(resObj.Crc, out st) || st == null) { st = new List <ResouceObj>(); _ObjectPoolDic.Add(resObj.Crc, st); } if (resObj.CloneObj) { if (recycleParent) { resObj.CloneObj.transform.SetParent(_RecycleNode); } else { resObj.CloneObj.SetActive(false); } } if (maxCacheCount < 0 || st.Count < maxCacheCount) { st.Add(resObj); resObj.AlreadyRelease = true; } else { //达到最大缓存个数 _ResourceObjDic.Remove(InstanceID); ResManager.Instance.ReleaseResource(resObj, st.Count, destoryCache); //_ResourceObjClassPool.Recycle(resObj); } } }
/// <summary> /// 取消异步加载 /// </summary> /// <param UIName="guid"></param> private void CancleLoad(long guid) { ResouceObj resObj = null; if (_AsyncResObjs.TryGetValue(guid, out resObj) && ResManager.Instance.CancleLoad(resObj)) { _AsyncResObjs.Remove(guid); //_ResourceObjClassPool.Recycle(resObj); } }
internal void CancleLoadAsset(int assetHelpHash, long guid) { ResouceObj resObj = null; if (_AsyncResObjs.TryGetValue(guid, out resObj) && ResManager.Instance.CancleLoad(resObj)) { ResManager.Instance.RemoveObjAsset(resObj.Crc, assetHelpHash); _AsyncResObjs.Remove(guid); //_ResourceObjClassPool.Recycle(resObj); } }
private GameObject InstantiateObject(string path, uint crc, ResLoadMode mode, bool clearChangeScene, bool setCreateNode) { ResouceObj resouceObj = null; try { resouceObj = GetObjectFromPool(crc); } catch (Exception e) { Debug.LogError(e); Debug.LogError("对象路径 Path :" + path); } if (resouceObj == null) { resouceObj = new ResouceObj();// _ResourceObjClassPool.Spawn(true); resouceObj.Crc = crc; resouceObj.ClearByChangeScene = clearChangeScene; //ResouceManager提供加载方法 resouceObj = ResManager.Instance.LoadRessource(path, mode, resouceObj); if (resouceObj.ResItem.Obj != null) { resouceObj.CloneObj = GameObject.Instantiate(resouceObj.ResItem.Obj) as GameObject; } } if (setCreateNode) { resouceObj.CloneObj.transform.SetParent(_CreateNode, false); } resouceObj.Guid = resouceObj.CloneObj.GetInstanceID(); if (!_ResourceObjDic.ContainsKey(resouceObj.Guid)) { _ResourceObjDic.Add(resouceObj.Guid, resouceObj); } //引用计数 加一 resouceObj.ResItem.RefCount.Increase(); return(resouceObj.CloneObj); }
/// <summary> /// 针对ObjectManager的异步加载接口 /// </summary> /// <param UIName="path"></param> /// <param UIName="resObj"></param> /// <param UIName="dealFinish"></param> /// <param UIName="priority"></param> internal void AsyncLoadResource(string path, ResLoadMode mode, ResouceObj resObj, OnAsyncFinish dealFinish, LoadResPriority priority) { ResItem item = GetCacheResouceItem(resObj.Crc); if (item != null) { resObj.ResItem = item; if (dealFinish != null) { dealFinish(path, resObj); } return; } //判断是否在加载中 AsyncLoadResParam param = null; if (!_LoadingAssetDic.TryGetValue(resObj.Crc, out param) || param == null) { param = _AsyncLoadResParamPool.Spawn(true); param.Crc = resObj.Crc; if (mode == ResLoadMode.Ab) { param.LoadMode = LoadResMode.AssetBundle; } else { param.LoadMode = LoadResMode.Resource; } param.Path = path; param.Priority = priority; _LoadingAssetDic.Add(resObj.Crc, param); _LoadingAssetList[(int)priority].Add(param); } //回调列表里面加回调 AsyncCallBack callBack = _AsyncCallBackPool.Spawn(true); callBack.OnFinish = dealFinish; callBack.ResObj = resObj; param.CallBackList.Add(callBack); }
/// <summary> /// 资源加载完成回调 /// </summary> /// <param UIName="path"></param> /// <param UIName="resObj"></param> /// <param UIName="param1"></param> /// <param UIName="param2"></param> /// <param UIName="param3"></param> private void OnLoadResourceObjFinish(string path, ResouceObj resObj, params object[] paramValues) { if (resObj == null) { return; } if (resObj.ResItem.Obj == null) { #if UNITY_EDITOR Debug.LogError("异步资源加载的资源为空 Path :" + path); #endif } else { resObj.CloneObj = GameObject.Instantiate(resObj.ResItem.Obj) as GameObject; } //加载完成就重正在加载的异步中移除 if (_AsyncResObjs.ContainsKey(resObj.Guid)) { _AsyncResObjs.Remove(resObj.Guid); } if (resObj.CloneObj != null && resObj.SetParent) { resObj.CloneObj.transform.SetParent(_CreateNode, false); } if (resObj.OnFinish != null) { int tempID = resObj.CloneObj.GetInstanceID(); if (!_ResourceObjDic.ContainsKey(tempID)) { _ResourceObjDic.Add(tempID, resObj); } resObj.ResItem.RefCount.Increase(); resObj.OnFinish(path, resObj.CloneObj, resObj.ParamValues); } }
/// <summary> /// 清空对象池 /// </summary> private void ClearCache(bool clearChangeScene) { uint[] clearKeys = _ObjectPoolDic.Keys.ToArray(); List <uint> tempList = new List <uint>(); foreach (uint key in clearKeys) { List <ResouceObj> st = _ObjectPoolDic[key]; for (int i = st.Count - 1; i >= 0; i--) { ResouceObj resObj = st[i]; if (!System.Object.ReferenceEquals(resObj.CloneObj, null)) { if (!clearChangeScene && resObj.ClearByChangeScene) { continue; } _ResourceObjDic.Remove(resObj.CloneObj.GetInstanceID()); ResManager.Instance.ReleaseResource(resObj, i, true); //_ResourceObjClassPool.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 (_ObjectPoolDic.ContainsKey(temp)) { _ObjectPoolDic.Remove(temp); } } tempList.Clear(); }
/// <summary> /// 异步对象加载 /// </summary> /// <param UIName="path"></param> /// <param UIName="fealFinish"></param> /// <param UIName="priority"></param> /// <param UIName="setSceneObject"></param> /// <param UIName="param1"></param> /// <param UIName="param2"></param> /// <param UIName="param3"></param> /// <param UIName="clearChangeScene"></param> private long InstantiateObjectAsync(string path, uint crc, ResLoadMode mode, OnAsyncObjFinish onFinish, LoadResPriority priority, bool setCreateNode = false, params object[] paramValues) { ResouceObj resObj = GetObjectFromPool(crc); if (resObj != null) { if (setCreateNode) { resObj.CloneObj.transform.SetParent(_CreateNode, false); } if (onFinish != null) { resObj.ResItem.RefCount.Increase(); onFinish(path, resObj.CloneObj, paramValues); } return(resObj.Guid); } long guid = ResManager.CreateGuid(); resObj = new ResouceObj();// _ResourceObjClassPool.Spawn(true); resObj.Crc = crc; resObj.SetParent = setCreateNode; resObj.OnFinish = onFinish; if (paramValues != null && paramValues.Length > 0) { foreach (object value in paramValues) { resObj.ParamList.Add(value); } } //调用ResourceManagerd的异步加载接口 ResManager.Instance.AsyncLoadResource(path, mode, resObj, OnLoadResourceObjFinish, priority); return(guid); }
/// <summary> /// 同步加载资源,针对ObjectManager的接口 /// </summary> /// <param UIName="path"></param> /// <param UIName="resObj"></param> /// <returns></returns> public ResouceObj LoadRessource(string path, ResLoadMode mode, ResouceObj resObj) { if (resObj == null) { return(null); } uint crc = resObj.Crc == 0 ? Crc32.GetCrc32(path) : resObj.Crc; ResItem item = GetCacheResouceItem(crc); if (item != null) { resObj.ResItem = item; return(resObj); } item = LoadResource <Object>(mode, path, crc); CacheResource(path, ref item, crc); resObj.ResItem = item; item.Clear = resObj.ClearByChangeScene; return(resObj); }
/// <summary> /// 该对象是否是对象池创建的 /// </summary> /// <returns></returns> private bool IsObjectManagerCreat(GameObject obj) { ResouceObj resObj = _ResourceObjDic[obj.GetInstanceID()]; return(resObj != null); }
/// <summary> /// 异步加载 /// </summary> /// <returns></returns> IEnumerator AsyncLoadCor() { List <AsyncCallBack> callBackList = null; //上一次yield的时间 long lastYieldTime = System.DateTime.Now.Ticks; while (true) { bool haveYield = false; for (int i = 0; i < (int)LoadResPriority.Res_Num; i++) { if (_LoadingAssetList[(int)LoadResPriority.Res_Hight].Count > 0) { i = (int)LoadResPriority.Res_Hight; } else if (_LoadingAssetList[(int)LoadResPriority.Res_Middle].Count > 0) { i = (int)LoadResPriority.Res_Middle; } List <AsyncLoadResParam> loadingList = _LoadingAssetList[i]; if (loadingList.Count <= 0) { continue; } AsyncLoadResParam loadingItem = loadingList[0]; loadingList.RemoveAt(0); callBackList = loadingItem.CallBackList; Object obj = null; ResItem item = null; #if UNITY_EDITOR if (IsEditorLoadMode) { if (item == null) { item = new ResItem(); item.Crc = loadingItem.Crc; } if (loadingItem.LoadMode == ResKit.LoadResMode.Resource) { ResourceRequest resRequest = null; if (loadingItem.ResType == typeof(Sprite)) { resRequest = Resources.LoadAsync <Sprite>(loadingItem.Path); } else { resRequest = Resources.LoadAsync <Object>(loadingItem.Path); } yield return(resRequest); if (resRequest.isDone) { obj = resRequest.asset; } lastYieldTime = System.DateTime.Now.Ticks; } else { if (loadingItem.ResType == typeof(Sprite)) { obj = LoadAssetByEditor <Sprite>(loadingItem.Path); } else { obj = LoadAssetByEditor <Object>(loadingItem.Path); } //模拟异步加载 yield return(new WaitForSeconds(0.2f)); } } #endif if (obj == null) { if (loadingItem.LoadMode == ResKit.LoadResMode.Resource) { if (item == null) { item = new ResItem(); item.Crc = loadingItem.Crc; } ResourceRequest resRequest = null; if (loadingItem.ResType == typeof(Sprite)) { resRequest = Resources.LoadAsync <Sprite>(loadingItem.Path); } else { resRequest = Resources.LoadAsync <Object>(loadingItem.Path); } yield return(resRequest); if (resRequest.isDone) { obj = resRequest.asset; } lastYieldTime = System.DateTime.Now.Ticks; } else { item = AssetBundleMgr.Instance.LoadResourceAssetBundle(loadingItem.Crc); if (item != null && item.AssetBundle != null) { AssetBundleRequest abRequest = null; if (loadingItem.ResType == typeof(Sprite)) { //是图片资源 abRequest = item.AssetBundle.LoadAssetAsync <Sprite>(item.AssetName); } else { //不是图片资源 abRequest = item.AssetBundle.LoadAssetAsync(item.AssetName); } yield return(abRequest); if (abRequest.isDone) { obj = abRequest.asset; } lastYieldTime = System.DateTime.Now.Ticks; } else { Debug.LogErrorFormat("加载AssetBundle失败 : 不能从AssetBundleConfig中找到 Path :{0}", loadingItem.Path); } } } item.Crc = loadingItem.Crc; item.Obj = obj; item.Guid = obj.GetInstanceID(); CacheResource(loadingItem.Path, ref item, loadingItem.Crc, callBackList.Count); for (int j = 0; j < callBackList.Count; j++) { AsyncCallBack callBack = callBackList[j]; if (callBack != null && callBack.OnFinish != null && callBack.ResObj != null) { ResouceObj tempResObj = callBack.ResObj; tempResObj.ResItem = item; callBack.OnFinish(loadingItem.Path, tempResObj, tempResObj.ParamValues); callBack.OnFinish = null; tempResObj = null; } if (callBack != null && callBack.OnObjFinish != null) { callBack.OnObjFinish(loadingItem.Path, obj, callBack.ParamValues); callBack.OnObjFinish = null; } callBack.Reset(); _AsyncCallBackPool.Recycle(callBack); } obj = null; callBackList.Clear(); _LoadingAssetDic.Remove(loadingItem.Crc); loadingItem.Reset(); _AsyncLoadResParamPool.Recycle(loadingItem); if (System.DateTime.Now.Ticks - lastYieldTime > _MaxLoadResTime) { yield return(null); lastYieldTime = System.DateTime.Now.Ticks; haveYield = true; } } //大于 _MaxLoadResTime 时间才等待一帧 if (!haveYield || System.DateTime.Now.Ticks - lastYieldTime > _MaxLoadResTime) { lastYieldTime = System.DateTime.Now.Ticks; yield return(null); } } }