Пример #1
0
        /// <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);
        }
Пример #2
0
 public void Reset()
 {
     OnObjFinish = null;
     OnFinish    = null;
     Params.Clear();
     ResObj = null;
 }
Пример #3
0
        /// <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);
            }
        }
Пример #4
0
        /// <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);
            }
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
                }
            }
        }
Пример #9
0
        /// <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);
            }
        }
Пример #10
0
        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);
            }
        }
Пример #11
0
        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);
        }
Пример #12
0
        /// <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);
        }
Пример #13
0
        /// <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);
            }
        }
Пример #14
0
        /// <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();
        }
Пример #15
0
        /// <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);
        }
Пример #16
0
        /// <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);
        }
Пример #17
0
        /// <summary>
        /// 该对象是否是对象池创建的
        /// </summary>
        /// <returns></returns>
        private bool IsObjectManagerCreat(GameObject obj)
        {
            ResouceObj resObj = _ResourceObjDic[obj.GetInstanceID()];

            return(resObj != null);
        }
Пример #18
0
        /// <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);
                }
            }
        }