Ejemplo n.º 1
0
 public void Reset()
 {
     m_DealFinish       = null;
     m_DealResObjFinish = null;
     m_Params           = null;
     m_ResObj           = null;
 }
Ejemplo n.º 2
0
        /// <summary>
        /// 清除某个资源在对象池中所有的对象
        /// </summary>
        /// <param name="crc"></param>
        public void ClearPoolObject(uint crc)
        {
            List <ResourceObj> st = null;

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

            for (int i = st.Count - 1; i >= 0; i--)
            {
                ResourceObj resObj = st[i];
                if (resObj.m_bClear)
                {
                    st.Remove(resObj);
                    int tempID = resObj.m_CloneObj.GetInstanceID();
                    GameObject.Destroy(resObj.m_CloneObj);
                    resObj.Reset();
                    m_ResObjDic.Remove(tempID);
                    m_ResObjClassPool.Recycle(resObj);
                }
            }

            if (st.Count == 0)
            {
                m_ObjectPoolDic.Remove(crc);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 取消异步加载资源
        /// </summary>
        /// <returns></returns>
        public bool CancleLoad(ResourceObj res)
        {
            AsyncLoadResUnit unit = null;

            //这俩个条件主要来判断该资源还没有进入到异步加载流程
            //多个人请求同一份资源,要多个人都取消才能取消这个异步加载单位
            //其中一个人取消异步加载,只是把应该给他的回调取消掉
            if (m_LoadingAssetDic.TryGetValue(res.m_Crc, out unit) &&
                m_loadingAssetList[(int)unit.m_Priority].Contains(unit))
            {
                for (int i = unit.m_CallBackList.Count - 1; i >= 0; i--)
                {
                    //取消对应的回调列表
                    AsynCallBack tempCallBack = unit.m_CallBackList[i];
                    if (tempCallBack != null && res == tempCallBack.m_ResObj)
                    {
                        tempCallBack.Reset();
                        m_AsynCallBackPool.Recycle(tempCallBack);
                        unit.m_CallBackList.Remove(tempCallBack);
                    }
                }
                //异步加载单位的回调列表为0,表示所有人都取消了这个资源加载,回收他
                if (unit.m_CallBackList.Count <= 0)
                {
                    unit.Reset();
                    m_loadingAssetList[(int)unit.m_Priority].Remove(unit);
                    m_AsyncLoadResParamPool.Recycle(unit);
                    m_LoadingAssetDic.Remove(res.m_Crc);
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 根据ResourceObj 卸载资源
        /// </summary>
        /// <param name="resObj"></param>
        /// <param name="destoryObj"></param>
        /// <returns></returns>
        public bool ReleaseResource(ResourceObj resObj, bool destoryObj = false)
        {
            if (resObj == null)
            {
                return(false);
            }

            uint crc = resObj.m_Crc;

            AssetBundleInfo abInfo = null;

            if (!AssetDic.TryGetValue(resObj.m_Crc, out abInfo) || null == abInfo)
            {
                Debug.LogError("该路径:" + resObj.m_CloneObj.name + "  的资源不存在!");
            }

            GameObject.Destroy(resObj.m_CloneObj);

            abInfo.RefCount--;

            DestoryResouceItem(abInfo, destoryObj);

            return(true);

            //return ReleaseResource(resourceObj.m_AssetBundleInfo.m_Obj, destoryObj);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 从对象池取出一个对象
        /// </summary>
        /// <param name="crc"></param>
        /// <returns></returns>
        protected ResourceObj GetObjectFromPool(uint crc)
        {
            List <ResourceObj> st = null;

            if (m_ObjectPoolDic.TryGetValue(crc, out st) && st != null && st.Count != 0)
            {
                //增加引用计数
                ResourceManager.Instance.IncreaseResourceRef(crc);


                ResourceObj resObj = st[0];
                st.RemoveAt(0);
                GameObject obj = resObj.m_CloneObj;
                if (!System.Object.ReferenceEquals(obj, null))
                {
                    //还原离线数据
                    if (!System.Object.ReferenceEquals(resObj.m_offlineData, null))
                    {
                        resObj.m_offlineData.ResetProp();
                    }

                    resObj.m_Already = false;
#if UNITY_EDITOR
                    if (obj.name.EndsWith("(Recycle)"))
                    {
                        obj.name = obj.name.Replace("(Recycle)", "");
                    }
#endif
                }

                return(resObj);
            }

            return(null);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 清空对象池
        /// </summary>
        public void ClearCache()
        {
            List <uint> tempList = new List <uint>();

            foreach (uint key in m_ObjectPoolDic.Keys)
            {
                List <ResourceObj> st = m_ObjectPoolDic[key];
                for (int i = st.Count - 1; i >= 0; i--)
                {
                    ResourceObj resObj = st[i];
                    if (!System.Object.ReferenceEquals(resObj.m_CloneObj, null) && resObj.m_bClear)
                    {
                        GameObject.Destroy(resObj.m_CloneObj);
                        m_ResObjDic.Remove(resObj.m_CloneObj.GetInstanceID());
                        resObj.Reset();
                        m_ResObjClassPool.Recycle(resObj);
                        st.Remove(resObj);
                    }
                }

                if (st.Count <= 0)
                {
                    tempList.Add(key);
                }
            }

            for (int i = 0; i < tempList.Count; i++)
            {
                if (m_ObjectPoolDic.ContainsKey(tempList[i]))
                {
                    m_ObjectPoolDic.Remove(tempList[i]);
                }
            }
            tempList.Clear();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 取消异步加载
        /// </summary>
        /// <param name="guid"></param>
        public void CancleLoad(long guid)
        {
            ResourceObj resObj = null;

            //根据GUID,找到正在异步加载的资源,并且该资源没有在加载中,回调列表数量是0
            if (m_AsyncResObjs.TryGetValue(guid, out resObj) && ResourceManager.Instance.CancleLoad(resObj))
            {
                m_AsyncResObjs.Remove(guid);

                resObj.Reset();
                m_ResObjClassPool.Recycle(resObj);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 根据实例化对象直接获取离线数据
        /// </summary>
        /// <returns></returns>
        public OfflineData FindOfflineData(GameObject obj)
        {
            OfflineData data   = null;
            ResourceObj resObj = null;

            m_ResObjDic.TryGetValue(obj.GetInstanceID(), out resObj);
            if (resObj != null)
            {
                data = resObj.m_offlineData;
            }

            return(data);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 异步加载
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fealFinish"></param>
        /// <param name="priority"></param>
        /// <param name="setSceneObj"></param>
        /// <param name="param1"></param>
        /// <param name="param2"></param>
        /// <param name="param3"></param>
        /// <param name="bClear"></param>
        public long InstantiateObjectAsync(string path, OnAsyncFinish dealFinish, LoadResPriority priority, bool setSceneObj = false,
                                           bool bClear = true, params object[] paramList)
        {
            if (string.IsNullOrEmpty(path))
            {
                return(0);
            }

            uint crc = Crc32.GetCrc32(path);
            //从缓存池获取
            ResourceObj resObj = GetObjectFromPool(crc);

            //从缓存中拿到了,直接返回
            if (resObj != null)
            {
                if (setSceneObj)
                {
                    resObj.m_CloneObj.transform.SetParent(SceneTrs, false);
                }

                if (dealFinish != null)
                {
                    dealFinish(path, resObj.m_CloneObj, paramList);
                }

                return(resObj.m_Guid);
            }

            //异步加载的GUID
            long guid = ResourceManager.Instance.CreateGuid();

            //缓存中没有,异步加载
            resObj                  = m_ResObjClassPool.Spawn(true); //new一个对象
            resObj.m_Crc            = crc;
            resObj.m_SetSceneParent = setSceneObj;
            resObj.m_bClear         = bClear;
            resObj.m_DealFinish     = dealFinish;
            resObj.m_Params         = paramList;

            //调用ResourceManager的异步加载接口
            ResourceManager.Instance.AsyncLoadResource(path, resObj, OnLoadResObjFinish, priority);
            return(guid);
        }
Ejemplo n.º 10
0
        /// <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 OnLoadResObjFinish(string path, ResourceObj resObj, params object[] paramList)
        {
            if (resObj == null)
            {
                return;
            }

            if (resObj.m_AssetBundleInfo.m_Obj == null)
            {
#if UNITY_EDITOR
                Debug.LogError("异步资源加载的资源为空:" + path);
#endif
            }
            else
            {
                //给ResourceObj的实例化对象赋值
                resObj.m_CloneObj = GameObject.Instantiate(resObj.m_AssetBundleInfo.m_Obj) as GameObject;

                resObj.m_offlineData = resObj.m_CloneObj.GetComponent <OfflineData>();
            }

            //加载完成,就从正在加载的异步中移除
            if (m_AsyncResObjs.ContainsKey(resObj.m_Guid))
            {
                m_AsyncResObjs.Remove(resObj.m_Guid);
            }

            if (resObj.m_CloneObj != null && resObj.m_SetSceneParent)
            {
                resObj.m_CloneObj.transform.SetParent(SceneTrs, false);
            }

            if (resObj.m_DealFinish != null)
            {
                int tempID = resObj.m_CloneObj.GetInstanceID();
                if (!m_ResObjDic.ContainsKey(tempID))
                {
                    m_ResObjDic.Add(tempID, resObj);
                }

                resObj.m_DealFinish(path, resObj.m_CloneObj, resObj.m_Params);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// 异步资源加载,针对ObjectManager的,(需要实例化对象的异步加载)
        /// </summary>
        public void AsyncLoadResource(string path, ResourceObj resObj, OnAsyncResObjFinish dealFinish, LoadResPriority priority, uint crc = 0, params object[] paramList)
        {
            AssetBundleInfo abInfo = GetCacheAssetBundleInfo(resObj.m_Crc);

            if (abInfo != null)
            {
                resObj.m_AssetBundleInfo = abInfo;
                if (dealFinish != null)
                {
                    dealFinish(path, resObj, paramList);
                }

                return;
            }
            //判断是否在加载中
            AsyncLoadResUnit unit = null;

            //没有找到这个异步加载单位,或者这个异步加载单位是空
            if (!m_LoadingAssetDic.TryGetValue(resObj.m_Crc, out unit) || unit == null)
            {
                unit            = m_AsyncLoadResParamPool.Spawn(true);
                unit.m_Crc      = resObj.m_Crc;
                unit.m_Path     = path;
                unit.m_Priority = priority;

                m_LoadingAssetDic.Add(resObj.m_Crc, unit);   //添加到正在异步加载的资源dic中

                m_loadingAssetList[(int)priority].Add(unit); //按照加载优先级,添加到对应的正在异步加载的资源列表中
            }

            //往回调列表里面添加回调
            AsynCallBack callBack = m_AsynCallBackPool.Spawn(true);

            callBack.m_Params = paramList;

            callBack.m_DealResObjFinish = dealFinish;
            callBack.m_ResObj           = resObj;
            //往这个异步加载单位的回调列表中添加一个回调
            //可能多个地方加载同一份资源,这样做只加载一次资源,
            //加载完了后,根据回调列表依次返回这份资源
            unit.m_CallBackList.Add(callBack);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// 同步加载
        /// </summary>
        /// <param name="path"></param>
        /// <param name="setSceneObj">是否存到</param>
        /// <param name="bClear">跳场景是否清空</param>
        /// <returns></returns>
        public GameObject InstantiateObject(string path, bool setSceneObj = false, bool bClear = true)
        {
            uint crc = Crc32.GetCrc32(path);
            //从缓存池获取
            ResourceObj resObj = GetObjectFromPool(crc);

            if (resObj == null)
            {
                resObj          = m_ResObjClassPool.Spawn(true);
                resObj.m_Crc    = crc;
                resObj.m_bClear = bClear;

                //ResourceManager提供加载方法
                //给resObj.m_AssetBundleInfo 赋值
                //给resObj.m_AssetBundleInfo.m_Obj赋值
                resObj = ResourceManager.Instance.LoadResource(path, resObj);

                if (resObj.m_AssetBundleInfo.m_Obj != null)
                {
                    resObj.m_CloneObj = GameObject.Instantiate(resObj.m_AssetBundleInfo.m_Obj) as GameObject;

                    resObj.m_offlineData = resObj.m_CloneObj.GetComponent <OfflineData>();
                }
            }

            //setParent会造成性能消耗,所以加个布尔值控制下
            if (setSceneObj)
            {
                resObj.m_CloneObj.transform.SetParent(SceneTrs, false);
            }

            int tempID = resObj.m_CloneObj.GetInstanceID();

            if (!m_ResObjDic.ContainsKey(tempID))
            {
                m_ResObjDic.Add(tempID, resObj);
            }

            return(resObj.m_CloneObj);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// 异步加载
        /// </summary>
        /// <returns></returns>
        IEnumerator AsyncLoadCor()
        {
            List <AsynCallBack> callBackList = null;

            while (true)
            {
                bool haveYield = false;     //是否已经等了一帧了
                                            //上次yield的时间
                long lastYiledTime = System.DateTime.Now.Ticks;

                //遍历优先级列表,从0开始,0表示最高
                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 <AsyncLoadResUnit> loadingList = m_loadingAssetList[i];
                    if (loadingList.Count <= 0)
                    {
                        continue;
                    }

                    AsyncLoadResUnit loadintItem = loadingList[0];
                    loadingList.RemoveAt(0);
                    callBackList = loadintItem.m_CallBackList;

                    Object          obj    = null;
                    AssetBundleInfo abInfo = null;
#if UNITY_EDITOR
                    if (!m_LoadFromAssetBundle)
                    {
                        if (loadintItem.m_Sprite) //判断是否是Sprite,因为Unity Object不能转换成Sprite
                        {
                            obj = LoadAssetByEditor <Sprite>(loadintItem.m_Path);
                        }
                        else
                        {
                            obj = LoadAssetByEditor <Object>(loadintItem.m_Path);
                        }

                        //编辑器下模拟异步加载,等0.1f
                        yield return(new WaitForSeconds(0.1f));

                        abInfo = AssetBundleManager.Instance.FindAssetBundleInfo(loadintItem.m_Crc);

                        if (abInfo == null)
                        {
                            abInfo       = new AssetBundleInfo();
                            abInfo.m_Crc = loadintItem.m_Crc;
                        }
                    }
#endif
                    if (obj == null)
                    {
                        abInfo = AssetBundleManager.Instance.LoadAssetBundleInfoAsync(loadintItem.m_Crc);
                        yield return(abInfo);

                        if (abInfo.isDone)
                        {
                            if (abInfo != null && abInfo.m_AssetBundle != null)
                            {
                                AssetBundleRequest abRequest = null;
                                if (loadintItem.m_Sprite)   //判断是否是Sprite,因为Unity Object不能转换成Sprite
                                {
                                    abRequest = abInfo.m_AssetBundle.LoadAssetAsync <Sprite>(abInfo.m_AssetName);
                                }
                                else
                                {
                                    abRequest = abInfo.m_AssetBundle.LoadAssetAsync(abInfo.m_AssetName);
                                }
                                yield return(abRequest);

                                if (abRequest.isDone)
                                {
                                    obj = abRequest.asset;
                                }

                                lastYiledTime = System.DateTime.Now.Ticks;
                            }
                        }
                    }

                    CacheAssetBundleInfo(loadintItem.m_Path, ref abInfo, loadintItem.m_Crc, obj, callBackList.Count);

                    //处理回调
                    for (int j = 0; j < callBackList.Count; j++)
                    {
                        AsynCallBack callBack = callBackList[j];

                        //实例化对象的回调
                        if (callBack != null && callBack.m_DealResObjFinish != null && callBack.m_ResObj != null)
                        {
                            ResourceObj tempResObj = callBack.m_ResObj;

                            tempResObj.m_AssetBundleInfo = abInfo;

                            callBack.m_DealResObjFinish(loadintItem.m_Path, tempResObj, callBack.m_Params);

                            callBack.m_DealResObjFinish = null;

                            tempResObj = null;
                        }

                        //非实例化对象的回调
                        if (callBack != null && callBack.m_DealFinish != null)
                        {
                            callBack.m_DealFinish(loadintItem.m_Path, obj, callBack.m_Params);
                            callBack.m_DealFinish = null;
                        }


                        callBack.Reset();       //还原回调,并且回收
                        m_AsynCallBackPool.Recycle(callBack);
                    }

                    obj = null;
                    callBackList.Clear();
                    m_LoadingAssetDic.Remove(loadintItem.m_Crc);
                    loadintItem.Reset();
                    m_AsyncLoadResParamPool.Recycle(loadintItem);

                    //加载一个资源时间过长,等一帧
                    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);
                }
            }
        }
Ejemplo n.º 14
0
 /// <summary>
 /// 根据Resobj减少引用计数
 /// </summary>
 /// <returns></returns>
 public int DecreaseResourceRef(ResourceObj resObj, int count = 1)
 {
     return(resObj != null?DecreaseResourceRef(resObj.m_Crc, count) : 0);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// 该对象是否是ObjectManager创建的
        /// </summary>
        /// <returns></returns>
        public bool IsObjectManagerCreate(GameObject obj)
        {
            ResourceObj resObj = m_ResObjDic[obj.GetInstanceID()];

            return(resObj == null ? false : true);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// 同步加载资源,针对给ObjectManager的接口
        /// 给ResourceObj.m_AssetBundleInfo赋值用的
        /// </summary>
        /// <param name="path"></param>
        /// <param name="resObj">传入的resourceObj,</param>
        /// <returns></returns>
        public ResourceObj LoadResource(string path, ResourceObj resObj)
        {
            if (resObj == null)
            {
                return(null);
            }

            //获取crc
            uint crc = resObj.m_Crc == 0 ? Crc32.GetCrc32(path) : resObj.m_Crc;

            //根据crc从缓存中获取 AssetBundle资源块信息
            AssetBundleInfo abInfo = GetCacheAssetBundleInfo(crc);

            if (abInfo != null)
            {
                resObj.m_AssetBundleInfo = abInfo;
                return(resObj);
            }

            Object obj = null;

#if UNITY_EDITOR
            if (!m_LoadFromAssetBundle)
            {
                abInfo = AssetBundleManager.Instance.FindAssetBundleInfo(crc);
                if (abInfo != null && abInfo.m_Obj != null)
                {
                    obj = abInfo.m_Obj;
                }
                else
                {
                    if (abInfo == null)
                    {
                        abInfo       = new AssetBundleInfo();
                        abInfo.m_Crc = crc;
                    }

                    obj = LoadAssetByEditor <Object>(path);
                }
            }
#endif
            //缓存中没有AssetBundle资源块信息,加载它
            if (obj == null)
            {
                abInfo = AssetBundleManager.Instance.LoadAssetBundleInfo(crc);

                if (abInfo != null && abInfo.m_AssetBundle != null)
                {
                    if (abInfo.m_Obj != null)
                    {
                        obj = abInfo.m_Obj;
                    }
                    else
                    {
                        obj = abInfo.m_AssetBundle.LoadAsset <Object>(abInfo.m_AssetName);
                    }
                }
            }

            //将加载的资源放入缓存中
            CacheAssetBundleInfo(path, ref abInfo, crc, obj);

            resObj.m_AssetBundleInfo = abInfo;

            abInfo.m_Clear = resObj.m_bClear;

            return(resObj);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// 回收资源
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="maxCacheCount"></param>
        /// <param name="destoryCache"></param>
        /// <param name="recycleParent">是否放回回收节点</param>
        public void ReleaseObject(GameObject obj, int maxCacheCount = -1, bool destoryCache = false, bool recycleParent = true)
        {
            if (obj == null)
            {
                return;
            }

            ResourceObj resObj = null;

            int temID = obj.GetInstanceID();

            if (!m_ResObjDic.TryGetValue(temID, out resObj))
            {
                Debug.Log(obj.name + "对象不是ObjectManager创建的!");
                return;
            }

            if (resObj == null)
            {
                Debug.LogError("缓存的ResourceObj为空");
            }

            if (resObj.m_Already)
            {
                Debug.LogError("该对象已经放回对象池了,检查自己是否清空引用");
                return;
            }

#if UNITY_EDITOR
            obj.name += "(Recycle)";
#endif
            List <ResourceObj> st = null;
            //不缓存
            if (maxCacheCount == 0)
            {
                m_ResObjDic.Remove(temID);

                ResourceManager.Instance.ReleaseResource(resObj, destoryCache);

                resObj.Reset();

                m_ResObjClassPool.Recycle(resObj);
            }
            else
            {   //回收到对象池
                if (!m_ObjectPoolDic.TryGetValue(resObj.m_Crc, out st) || st == null)
                {
                    st = new List <ResourceObj>();
                    m_ObjectPoolDic.Add(resObj.m_Crc, st);
                }

                if (resObj.m_CloneObj)
                {
                    if (recycleParent)       //放到资源回收池节点下
                    {
                        resObj.m_CloneObj.transform.SetParent(RecyclePoolTrs);
                    }
                    else
                    {
                        resObj.m_CloneObj.SetActive(false);
                    }
                }

                //不限制最大缓存数量,或者当前缓存数量小于最大缓存数量
                if (maxCacheCount < 0 || st.Count < maxCacheCount)
                {
                    st.Add(resObj);

                    resObj.m_Already = true;
                    //ResourceManager做一个引用计数
                    ResourceManager.Instance.DecreaseResourceRef(resObj);
                }
                else
                {
                    m_ResObjDic.Remove(temID);
                    ResourceManager.Instance.ReleaseResource(resObj, destoryCache);
                    resObj.Reset();
                    m_ResObjClassPool.Recycle(resObj);
                }
            }
        }