Beispiel #1
0
        /// <summary>
        /// 不需要实例化的资源卸载,根据路径
        /// </summary>
        /// <param UIName="path"></param>
        /// <param UIName="destroyOjb"></param>
        /// <returns></returns>
        internal bool ReleaseResource(string path, uint crc, bool destroyRes = true)
        {
            if (string.IsNullOrEmpty(path))
            {
                Debug.LogError("释放资源的路径为null");
                return(false);
            }

            if (crc == 0)
            {
                crc = Crc32.GetCrc32(path);
            }


            ResItem item = null;

            if (!_UsededResCacheDic.TryGetValue(crc, out item) || item == null)
            {
                Debug.LogError("不存在该资源 Path: " + path + " 可能多次释放");
                return(false);
            }
            item.RefCount.Decrease();

            DestroyResourceItem(item, destroyRes);
            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// 预加载资源
        /// </summary>
        public void PreloadResource <T>(string path, uint crc = 0, ResLoadMode mode = ResLoadMode.Null) where T : UnityEngine.Object
        {
            if (string.IsNullOrEmpty(path))
            {
                return;
            }
            if (mode == ResLoadMode.Null)
            {
                mode = LoadMode(ref path);
            }
            if (crc == 0)
            {
                crc = Crc32.GetCrc32(path);
            }
            ResItem item = GetCacheResouceItem(crc, 0);

            if (item != null)
            {
                return;
            }

            //资源加载
            item = LoadResource <T>(mode, path, crc);

            //缓存
            CacheResource(path, ref item, crc);
            //跳场景不清空缓存
            item.Clear = false;
            ReleaseResource(item.Obj, false);
        }
Beispiel #3
0
        public ResItem LoadResourceAssetBundle(uint crc)
        {
            ResItem item = null;

            if (!_ResouceItemDic.TryGetValue(crc, out item) || item == null)
            {
                return(item);
            }

            if (item.AssetBundle != null)
            {
                return(item);
            }

            item.AssetBundle = LoadAssetBundle(item.ABName);

            if (item.DependAssetBundle != null)
            {
                for (int i = 0; i < item.DependAssetBundle.Count; i++)
                {
                    LoadAssetBundle(item.DependAssetBundle[i]);
                }
            }

            return(item);
        }
Beispiel #4
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);
        }
Beispiel #5
0
        /// <summary>
        /// 根据crc查找ResourceItem
        /// </summary>
        /// <param UIName="crc"></param>
        /// <returns></returns>
        public ResItem FindResourceItem(uint crc)
        {
            ResItem item = null;

            _ResouceItemDic.TryGetValue(crc, out item);
            return(item);
        }
Beispiel #6
0
        /// <summary>
        /// 同步资源加载 , 外部直接调用,仅加载不需要实例化的资源,例如Texture,Audio
        /// </summary>
        /// <typeparam UIName="T"></typeparam>
        /// <param UIName="path"></param>
        /// <returns></returns>
        internal T LoadResource <T>(string path, uint crc = 0, ResLoadMode mode = ResLoadMode.Null) where T : UnityEngine.Object
        {
            if (string.IsNullOrEmpty(path))
            {
                Debug.LogError("路径为null");
                return(null);
            }

            if (mode == ResLoadMode.Null)
            {
                mode = LoadMode(ref path);
            }
            if (crc == 0)
            {
                crc = Crc32.GetCrc32(path);
            }

            ResItem item = GetCacheResouceItem(crc);

            if (item != null)
            {
                return(item.Obj as T);
            }

            //资源加载
            item = LoadResource <T>(mode, path, crc);
            CacheResource(path, ref item, crc);
            //Debug.Log(item.Obj.name);
            return(item.Obj as T);
        }
Beispiel #7
0
        /// <summary>
        /// 异步加载资源 (仅仅是不需要实例化的资源)
        /// </summary>
        private void AsyncLoadResource <T>(string path, OnAsyncObjFinish onFinish, uint crc = 0, ResLoadMode mode = ResLoadMode.Null,
                                           LoadResPriority priority = LoadResPriority.Res_Slow, params object[] paramValues)
            where T : UnityEngine.Object
        {
            if (mode == ResLoadMode.Null)
            {
                mode = LoadMode(ref path);
            }
            if (crc == 0)
            {
                crc = Crc32.GetCrc32(path);
            }

            ResItem item = GetCacheResouceItem(crc);

            if (item != null)
            {
                if (onFinish != null)
                {
                    onFinish(path, item.Obj, paramValues);
                }

                return;
            }

            //判断是否在加载中
            AsyncLoadResParam param = null;

            if (!_LoadingAssetDic.TryGetValue(crc, out param) || param == null)
            {
                param          = _AsyncLoadResParamPool.Spawn(true);
                param.Crc      = crc;
                param.Path     = path;
                param.Priority = priority;
                param.ResType  = typeof(T);
                param.LoadMode = JudgeLoadMode(mode);
                _LoadingAssetDic.Add(crc, param);
                _LoadingAssetList[(int)priority].Add(param);
            }

            //回调列表里面加回调
            AsyncCallBack callBack = _AsyncCallBackPool.Spawn(true);

            callBack.OnObjFinish = onFinish;
            if (paramValues != null && paramValues.Length > 0)
            {
                foreach (object value in paramValues)
                {
                    callBack.Params.Add(value);
                }
            }

            param.CallBackList.Add(callBack);
        }
Beispiel #8
0
 public void Reset()
 {
     Crc                = 0;
     ResItem            = null;
     CloneObj           = null;
     ClearByChangeScene = true;
     Guid               = 0;
     AlreadyRelease     = false;
     SetParent          = false;
     OnFinish           = null;
     ParamList.Clear();
 }
Beispiel #9
0
        /// <summary>
        /// 卸载 不需要的实例化资源 根据对象
        /// </summary>
        /// <param UIName="obj"></param>
        /// <param UIName="destroyOjb"></param>
        /// <returns></returns>
        private bool ReleaseResource(ResItem item, bool destroyRes = true)
        {
            if (item == null)
            {
                Debug.LogError("不存在该资源 obj: " + item.Obj.name + " 可能多次释放");
                return(false);
            }

            item.RefCount.Decrease();
            DestroyResourceItem(item, destroyRes);
            return(true);
        }
Beispiel #10
0
 /// <summary>
 /// 缓存太多, 清除最早没有使用的资源
 /// </summary>
 protected void WashOut()
 {
     // 当前内存使用大于80% 时候 清除最早没有使用的资源
     //当大于好吃个数时进行一半释放
     while (_NoRefrenceAssetMapList.Size() >= _MaxCacheCount)
     {
         for (int i = 0; i < _MaxCacheCount / 2; i++)
         {
             ResItem item = _NoRefrenceAssetMapList.Back();
             DestroyResourceItem(item, true);
         }
     }
 }
Beispiel #11
0
        /// <summary>
        /// 从缓存中获取resourceItem
        /// </summary>
        /// <param UIName="crc"></param>
        /// <param UIName="addRefcount"></param>
        /// <returns></returns>
        ResItem GetCacheResouceItem(uint crc, int addRefcount = 1)
        {
            ResItem item = null;

            if (_UsededResCacheDic.TryGetValue(crc, out item) && item != null)
            {
                if (item.RefCount.count == 0)
                {
                    item.RefCount.Increase(addRefcount);
                }
            }
            return(item);
        }
Beispiel #12
0
        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param UIName="item"></param>
        public void ReleaseAsset(ResItem item)
        {
            if (item == null)
            {
                return;
            }

            if (item.DependAssetBundle != null && item.DependAssetBundle.Count > 0)
            {
                for (int i = 0; i < item.DependAssetBundle.Count; i++)
                {
                    UnLoadAssetBundle(item.DependAssetBundle[i]);
                }
            }

            UnLoadAssetBundle(item.ABName);
        }
Beispiel #13
0
        /// <summary>
        /// 卸载 不需要的实例化资源 根据对象
        /// </summary>
        /// <param UIName="obj"></param>
        /// <param UIName="destroyOjb"></param>
        /// <returns></returns>
        private bool ReleaseResource(Object obj, bool destroyRes = true)
        {
            if (obj == null)
            {
                Debug.LogError("释放资源的对象为null");
                return(false);
            }

            ResItem item = null;

            foreach (var res in _UsededResCacheDic.Values)
            {
                if (res.Guid == obj.GetInstanceID())
                {
                    item = res;
                }
            }
            return(ReleaseResource(item, destroyRes));
        }
Beispiel #14
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);
        }
Beispiel #15
0
        /// <summary>
        /// 加载AB配置表
        /// </summary>
        /// <returns></returns>
        public void LoadAssetBundleConfig()
        {
            _ResouceItemDic.Clear();

            string configPath = AssetBundlePath + "/assetbundleconfig";

#if UNITY_EDITOR
            if (!File.Exists(configPath))
            {
                Debug.LogError("assetbundleconfig 文件不存在, 没有进行打包 path " + configPath);
            }
#endif
            AssetBundle configAB  = AssetBundle.LoadFromFile(configPath);
            TextAsset   textAsset = configAB.LoadAsset <TextAsset>("AssetBundleConfig.bytes");

            AssetBundleConfig config;
            using (MemoryStream ms = new MemoryStream(textAsset.bytes))
            {
                BinaryFormatter bf = new BinaryFormatter();
                config = (AssetBundleConfig)bf.Deserialize(ms);
            }

            for (int i = 0; i < config.ABList.Count; i++)
            {
                ABBase  abBase = config.ABList[i];
                ResItem item   = new ResItem();
                item.Crc               = abBase.Crc;
                item.AssetName         = abBase.AssetName;
                item.ABName            = abBase.ABName;
                item.DependAssetBundle = abBase.ABDependence;

                if (_ResouceItemDic.ContainsKey(item.Crc))
                {
                    Debug.LogError("重复的Crc  资源名:" + item.AssetName + "ab包名:" + item.ABName);
                }
                else
                {
                    _ResouceItemDic.Add(item.Crc, item);
                }
            }
        }
Beispiel #16
0
        /// <summary>
        /// 不需要实例化的资源卸载,根据路径 AssetHelp
        /// </summary>
        /// <param UIName="path"></param>
        /// <param UIName="destroyOjb"></param>
        /// <returns></returns>
        internal bool ReleaseAsset(uint crc, int count = 1)
        {
            ResItem item = null;

            if (!_UsededResCacheDic.TryGetValue(crc, out item) || item == null)
            {
                return(false);
            }

            //预加载没有使用的资源 引用为0
            if (item.RefCount.count > 0)
            {
                if (count > item.RefCount.count)
                {
                    count = item.RefCount.count;
                }
                item.RefCount.Decrease(count);
            }

            DestroyResourceItem(item, true);
            return(true);
        }
Beispiel #17
0
        /// <summary>
        /// 缓存加载的资源
        /// </summary>
        /// <param UIName="path"></param>
        /// <param UIName="item"></param>
        /// <param UIName="crc"></param>
        /// <param UIName="obj"></param>
        /// <param UIName="addrefcount"></param>
        void CacheResource(string path, ref ResItem item, uint crc, int addrefcount = 1)
        {
            //缓存太多,清除最早没有使用的资源
            WashOut();

            if (item == null)
            {
                Debug.LogError("没有创建ResItem  Path : " + path);
            }

            item.RefCount.Increase(addrefcount);
            ResItem oldItem = null;

            if (_UsededResCacheDic.TryGetValue(crc, out oldItem))
            {
                _UsededResCacheDic[item.Crc] = item;
            }
            else
            {
                _UsededResCacheDic.Add(item.Crc, item);
            }
        }
Beispiel #18
0
        /// <summary>
        /// 卸载 不需要的实例化资源 根据对象
        /// </summary>
        /// <param UIName="obj"></param>
        /// <param UIName="destroyOjb"></param>
        /// <returns></returns>
        internal bool ReleaseResourceAsset(UnityEngine.Object obj, int assetHelpHash, bool destroyRes = true)
        {
            if (obj == null)
            {
                Debug.LogError("释放资源的对象为null");
                return(false);
            }

            ResItem item = null;

            foreach (var res in _UsededResCacheDic.Values)
            {
                if (res.Guid == obj.GetInstanceID())
                {
                    item = res;
                }
            }

            uint crc = item.Crc;

            RemoveResAsset(crc, assetHelpHash);
            return(ReleaseResource(item, destroyRes));
        }
Beispiel #19
0
        /// <summary>
        /// 回收一个资源
        /// </summary>
        /// <param UIName="item"></param>
        /// <param UIName="destroy"></param>
        internal void DestroyResourceItem(ResItem item, bool destroyCache = false)
        {
            Debug.Log(item.RefCount.count + "资源卸载");
            if (item == null || item.RefCount.count > 0)
            {
                return;
            }

            if (!destroyCache)
            {
                _NoRefrenceAssetMapList.InsertToHead(item);
                return;
            }

            if (!_UsededResCacheDic.Remove(item.Crc))
            {
                return;
            }

            _NoRefrenceAssetMapList.Remove(item);

            //释放AssetBundle引用
            AssetBundleMgr.Instance.ReleaseAsset(item);

            //清空资源对应的对象池资源
            ObjManager.Instance.ClearPoolObject(item.Crc);

            if (item.Obj != null)
            {
                item.Obj = null;

#if UNITY_EDITOR
                Debug.Log("卸载完成");
                Resources.UnloadUnusedAssets();
#endif
            }
        }
Beispiel #20
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);
        }
Beispiel #21
0
        private ResItem LoadResource <T>(ResLoadMode mode, string path, uint crc) where T : UnityEngine.Object
        {
            T       obj  = null;
            ResItem item = null;

#if UNITY_EDITOR
            if (IsEditorLoadMode)
            {
                if (JudgeLoadMode(mode) == LoadResMode.Resource)
                {
                    obj = Resources.Load <T>(path);
                }
                else
                {
                    obj = LoadAssetByEditor <T>(path);
                }
            }
#endif
            if (obj == null)
            {
                if (JudgeLoadMode(mode) == LoadResMode.Resource)
                {
                    obj = Resources.Load <T>(path);
                }
                else
                {
                    item = AssetBundleMgr.Instance.LoadResourceAssetBundle(crc);
                    if (item != null && item.AssetBundle != null)
                    {
                        if (item.Obj != null)
                        {
                            obj = item.Obj as T;
                        }
                        else
                        {
                            Debug.Log("AssetBundle模型下加载");
                            obj = item.AssetBundle.LoadAsset <T>(item.AssetName);
                        }
                    }
                    else
                    {
                        Debug.LogErrorFormat("加载AssetBundle失败 : 不能从AssetBundleConfig中找到 Path :{0}", path);
                    }
                }
            }

            if (obj == null)
            {
                Debug.LogError("加载资源失败,请检查资源[加载模式] mode ;" + loadResMode + " [路径] Path:" + path);
            }

            if (item == null)
            {
                item = new ResItem();
            }
            item.Crc = crc;
            item.Obj = obj;
            if (obj)
            {
                item.Guid = obj.GetInstanceID();
            }
            return(item);
        }
Beispiel #22
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);
                }
            }
        }