コード例 #1
0
    public void ClearCacheByCrc(uint crc)
    {
        List <ResourceGameObject> tList = null;

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

        for (int i = tList.Count - 1; i >= 0; i++)
        {
            ResourceGameObject resGo = tList[i];
            if (resGo != null && resGo.IsClear)
            {
                tList.Remove(resGo);
                resGo.Reset();
                m_resGoClassPool.Recycle(resGo);

                var guid = resGo.GoGuid;
                if (m_guidResGoDic.ContainsKey(guid))
                {
                    m_guidResGoDic.Remove(guid);
                }
            }
        }
        if (tList.Count <= 0)
        {
            if (m_resGoObjectPoolDic.ContainsKey(crc))
            {
                m_resGoObjectPoolDic.Remove(crc);
            }
        }
    }
コード例 #2
0
    /// <summary>
    /// 在回收池查找有没有空闲的resGo
    /// </summary>
    private ResourceGameObject GetResGoFromRecycleDic(uint crc)
    {
        ResourceGameObject        resGo    = null;
        List <ResourceGameObject> tempList = null;

        if (m_resGoObjectPoolDic.TryGetValue(crc, out tempList) && tempList.Count > 0)
        {
            resGo = tempList[0];
            tempList.RemoveAt(0);
            GameObject go = resGo.CloneGo;

            ResourcesManager.Instance.IncreaseResGoRefCount(resGo);  //取出时,增加ABDataItem的引用计数
            //判断go的是否被引用了,还有引用的话,要重置IsRecycle
            if (!System.Object.ReferenceEquals(go, null))
            {
                resGo.IsRecycle = false;
            }
#if UNITY_EDITOR
            if (go.name.EndsWith("(Recycle)"))
            {
                go.name = go.name.Replace("(Recycle)", "");
            }
            if (!go.activeInHierarchy)
            {
                go.SetActive(true);
            }
#endif
        }
        return(resGo);
    }
コード例 #3
0
    /// <summary>
    /// 内层异步加载完成的回调,用来实例化对象,并且执行外层的异步加载完成的回调
    /// </summary>
    /// <param name="path"></param>
    /// <param name="resGo"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    public void OnAsyncLoadResGoDealFinish(string path, ResourceGameObject resGo, object param1 = null, object param2 = null, object param3 = null)
    {
        if (resGo == null)
        {
            return;
        }
        if (resGo.ABDataItem == null)
        {
            Debug.LogError("没有加载ABDataItem,请检查ResourceManager中的协程方法");
            return;
        }
        if (resGo.ABDataItem.Obj != null)
        {
            resGo.CloneGo = GameObject.Instantiate(resGo.ABDataItem.Obj) as GameObject;
            resGo.GoGuid  = resGo.CloneGo.GetInstanceID();

            m_cancelIdResGoDic.Remove(resGo.CancelId);

            if (!m_guidResGoDic.ContainsKey(resGo.GoGuid))
            {
                m_guidResGoDic.Add(resGo.GoGuid, resGo);
            }

            if (resGo.DealFinish != null)
            {
                resGo.DealFinish(path, resGo.CloneGo, param1, param2, param3);
            }
        }
    }
コード例 #4
0
    /// <summary>
    /// 同步加载实例化对象
    /// </summary>
    /// <param name="path"></param>
    /// <param name="isSetSceneTr"></param>
    /// <param name="isClear"></param>
    /// <returns></returns>
    public GameObject InstantiateGameObj(string path, bool isSetSceneTr = true, bool isClear = true)
    {
        uint pathCrc             = Crc32.GetCRC32(path);
        ResourceGameObject resGo = GetResGoFromRecycleDic(pathCrc);

        if (resGo == null)
        {
            resGo     = m_resGoClassPool.Create(true);
            resGo.Crc = pathCrc;
            //加载resGo的abDataItem等
            ResourcesManager.Instance.LoadResourceGameObj(path, ref resGo);
            if (resGo.ABDataItem.Obj != null)
            {
                resGo.CloneGo = GameObject.Instantiate(resGo.ABDataItem.Obj) as GameObject;
            }

            resGo.IsClear = isClear;
            resGo.GoGuid  = resGo.CloneGo.GetInstanceID();

            if (!m_guidResGoDic.ContainsKey(resGo.GoGuid))
            {
                m_guidResGoDic.Add(resGo.GoGuid, resGo);
            }
        }
        if (isSetSceneTr)
        {
            resGo.CloneGo.transform.SetParent(SceneTr);
        }
        return(resGo.CloneGo);
    }
コード例 #5
0
    /// <summary>
    /// 给ObjectsManager提供的接口,加载resGo
    /// </summary>
    public void AsyncLoadResource(string path, ResourceGameObject resGo, AsyncLoadResGoDealFinish resGoDealFinish)
    {
        uint pathCrc = Crc32.GetCRC32(path);
        AssetBundleDataItem dataItem = GetCacheABDataItem(pathCrc);

        if (dataItem != null)
        {
            resGo.ABDataItem = dataItem;

            if (resGoDealFinish != null)
            {
                resGoDealFinish(path, resGo, resGo.Param1, resGo.Param2, resGo.Param3);
            }
            return;
        }

        AsyncLoadDataItem asyncDataItem = null;

        if (!m_asyncLoadingItemDic.TryGetValue(pathCrc, out asyncDataItem) && asyncDataItem == null)
        {
            asyncDataItem          = m_asyncDataItemPool.Create(true);
            asyncDataItem.Path     = path;
            asyncDataItem.Crc      = pathCrc;
            asyncDataItem.Priority = resGo.Priority;
            m_asyncLoadItemListArray[(int)resGo.Priority].Add(asyncDataItem);
            m_asyncLoadingItemDic.Add(pathCrc, asyncDataItem);
        }
        AsyncLoadCallBack callBack = m_asyncCallBackPool.Create(true);

        callBack.ResGoDealFinish = resGoDealFinish;
        callBack.resGo           = resGo;
        asyncDataItem.CallBackList.Add(callBack);
    }
コード例 #6
0
    //-----------------------------------------------------------------------
    #region   提供给ObjectsManager的接口
    /// <summary>
    /// 给ObjectsManager提供的接口:加载ResourceObj的ABDataItem等
    /// </summary>
    /// <param name="path"></param>
    /// <param name="resObj"></param>
    public bool LoadResourceGameObj(string path, ref ResourceGameObject resObj)
    {
        if (resObj == null || string.IsNullOrEmpty(path))
        {
            return(false);
        }
        uint pathCrc = Crc32.GetCRC32(path);
        AssetBundleDataItem dataItem = null;

        dataItem = GetCacheABDataItem(pathCrc);
        if (dataItem != null && dataItem.Obj != null)
        {
            resObj.ABDataItem = dataItem;
            return(true);
        }

        Object obj = null;

#if UNITY_EDITOR
        if (!GameRoot.m_UseAssetBundleInEditor)
        {
            dataItem = AssetBundleManager.Instance.GetABDataItem(pathCrc);
            if (dataItem != null && dataItem.Obj != null)
            {
                obj = dataItem.Obj;
            }
            else
            {
                obj = LoadABDataItemInEditorMode <Object>(path);
            }
            if (dataItem == null)
            {
                dataItem     = new AssetBundleDataItem();
                dataItem.Crc = pathCrc;
            }
        }
#endif

        if (obj == null)
        {
            dataItem = AssetBundleManager.Instance.LoadABDataItem(pathCrc);
            if (dataItem != null && dataItem.AB != null)
            {
                if (dataItem.Obj != null)
                {
                    obj = dataItem.Obj;
                }
                else
                {
                    obj = dataItem.AB.LoadAsset <Object>(dataItem.AssetName);
                }
            }
        }
        CacheABDataItem(path, ref dataItem, obj);

        resObj.ABDataItem = dataItem;
        dataItem.IsClear  = resObj.IsClear;

        return(true);
    }
コード例 #7
0
    public bool CancelAsyncLoad(ResourceGameObject resGo)
    {
        AsyncLoadDataItem asyncDataItem = null;

        //判断正在加载的字典中是否包含asyncDataItem, 并且没有进入异步的for循环
        if (m_asyncLoadingItemDic.TryGetValue(resGo.Crc, out asyncDataItem) && m_asyncLoadItemListArray[(int)resGo.Priority].Contains(asyncDataItem))
        {
            //重置callbackList
            var callBackList = asyncDataItem.CallBackList;
            for (int i = callBackList.Count - 1; i >= 0; i--)
            {
                //回收回调(可能有多个回调)
                AsyncLoadCallBack callBack = callBackList[i];
                if (callBack != null)
                {
                    callBack.Reset();
                    callBackList.Remove(callBack);
                    m_asyncCallBackPool.Recycle(callBack);
                }
            }
            if (callBackList.Count <= 0)
            {
                //只有全部回调都移除了才能真正取消异步加载
                asyncDataItem.Reset();
                m_asyncLoadingItemDic.Remove(resGo.Crc);
                m_asyncLoadItemListArray[(int)resGo.Priority].Remove(asyncDataItem);
                m_asyncDataItemPool.Recycle(asyncDataItem);
                return(true);
            }
        }

        return(false);
    }
コード例 #8
0
 public void Reset()
 {
     ResGoDealFinish = null;
     resGo           = null;
     DealFinish      = null;
     Param1          = null;
     Param2          = null;
     Param3          = null;
 }
コード例 #9
0
    /// <summary>
    /// 根据resGo释放资源
    /// </summary>
    public bool ReleaseResources(ResourceGameObject resGo, bool isDestroy = true)
    {
        if (resGo == null)
        {
            return(false);
        }
        AssetBundleDataItem dataItem = m_crcAssetDic[resGo.Crc];

        if (dataItem == null)
        {
            Debug.LogError(string.Format("不存在对应pathCrc的ABDataItem: {0}, {1}", resGo.Crc, resGo.CloneGo.name));
            return(false);
        }
        //销毁对象
        GameObject.Destroy(resGo.CloneGo);

        dataItem.RefCount--;
        ReleaseABDataItem(dataItem, isDestroy);
        return(true);
    }
コード例 #10
0
    /// <summary>
    /// 异步加载实例化对象
    /// </summary>
    /// <param name="path"></param>
    /// <param name="dealFinish">外层调用时传入的加载完成回调</param>
    /// <param name="priority"></param>
    /// <param name="isSetSceneTr">是否设置到场景节点</param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="isClear">是否跳转场景销毁/清除</param>
    public long AsyncInstantiateGameObj(string path, AsyncLoadDealFinish dealFinish, AsyncLoadPriority priority, bool isSetSceneTr = false,
                                        object param1 = null, object param2 = null, object param3 = null, bool isClear = true)
    {
        uint pathCrc             = Crc32.GetCRC32(path);
        ResourceGameObject resGo = GetResGoFromRecycleDic(pathCrc);

        if (resGo != null)
        {
            if (isSetSceneTr)
            {
                resGo.CloneGo.transform.SetParent(SceneTr);
            }

            if (dealFinish != null)
            {
                dealFinish(path, resGo.CloneGo, param1, param2, param3);
            }

            return(resGo.CancelId);
        }

        resGo              = m_resGoClassPool.Create(true);
        resGo.Crc          = pathCrc;
        resGo.IsClear      = isClear;
        resGo.IsSetSceneTr = isSetSceneTr;
        resGo.Priority     = priority;
        resGo.DealFinish   = dealFinish;
        resGo.Param1       = param1;
        resGo.Param2       = param2;
        resGo.Param3       = param3;
        ResourcesManager.Instance.AsyncLoadResource(path, resGo, OnAsyncLoadResGoDealFinish);

        resGo.CancelId = CreateCancelId();
        m_cancelIdResGoDic.Add(CancelId, resGo);

        return(resGo.CancelId);
    }
コード例 #11
0
    /// <summary>
    /// 清空对象池
    /// </summary>
    public void ClearCache()
    {
        List <uint> uintList = new List <uint>();

        foreach (uint crc in m_resGoObjectPoolDic.Keys)
        {
            List <ResourceGameObject> tList = m_resGoObjectPoolDic[crc];
            for (int i = tList.Count - 1; i >= 0; i++)
            {
                ResourceGameObject resGo = tList[i];
                if (resGo != null && resGo.IsClear)
                {
                    GameObject.Destroy(resGo.CloneGo);
                    tList.Remove(resGo);
                    resGo.Reset();
                    m_guidResGoDic.Remove(resGo.CloneGo.GetInstanceID());
                    m_resGoClassPool.Recycle(resGo);
                }

                if (tList.Count <= 0)
                {
                    uintList.Add(crc);
                }
            }
        }

        for (int i = 0; i < uintList.Count; i++)
        {
            if (m_resGoObjectPoolDic.ContainsKey(uintList[i]))
            {
                m_resGoObjectPoolDic.Remove(uintList[i]);
            }
        }

        uintList.Clear();
    }
コード例 #12
0
    /// <summary>
    /// 根据go回收
    /// </summary>
    /// <param name="go"></param>
    /// <param name="maxRecycleCount">最大的回收数量, -1表示不限制数量</param>
    /// <param name="isDestroy">是否销毁</param>
    /// <param name="toParent">是否设置到父节点(RecycleObjectsTr:对象池节点)</param>
    public void ReleaseGameObject(GameObject go, int maxRecycleCount = -1, bool isDestroy = false, bool toParent = false)
    {
        if (go == null)
        {
            Debug.Log("需要释放的go为null");
            return;
        }

        ResourceGameObject resGo = null;
        int tempId = go.GetInstanceID();

        if (!m_guidResGoDic.TryGetValue(tempId, out resGo) || resGo == null)
        {
            Debug.Log("此回收对象非ObjectsManager创建,找不到对应Guid的ResourceObj");
            return;
        }
        if (maxRecycleCount == 0) //不回收
        {
            m_guidResGoDic.Remove(tempId);
            ResourcesManager.Instance.ReleaseResources(resGo, isDestroy);
            resGo.Reset();
            m_resGoClassPool.Recycle(resGo);
        }
        else
        {
            uint pathCrc = resGo.Crc;
            if (!m_resGoObjectPoolDic.ContainsKey(pathCrc))
            {
                m_resGoObjectPoolDic.Add(pathCrc, new List <ResourceGameObject>());
            }

            List <ResourceGameObject> tempList = m_resGoObjectPoolDic[pathCrc];
            if (tempList.Count < maxRecycleCount || maxRecycleCount < 0)
            {
#if UNITY_EDITOR
                go.name += "(Recycle)";
#endif
                if (resGo.IsRecycle == false)
                {
                    //回收
                    ResourcesManager.Instance.DecreaseResGoRefCount(resGo);
                    resGo.IsRecycle = true;
                    tempList.Add(resGo);
                }
                if (toParent)
                {
                    go.transform.SetParent(RecycleObjectsTr);
                }
                else
                {
                    go.SetActive(false);
                }
            }
            else
            {
                m_guidResGoDic.Remove(tempId);
                ResourcesManager.Instance.ReleaseResources(resGo, isDestroy);
                resGo.Reset();
                m_resGoClassPool.Recycle(resGo);
            }
        }
    }
コード例 #13
0
    private IEnumerator AsyncLoadCoroutine()
    {
        long preYieldTime = System.DateTime.Now.Ticks;    //上一次返回的时间点
        List <AsyncLoadCallBack> callBackList = null;

        while (true)
        {
            bool hadYield = false;
            for (int i = 0; i < (int)AsyncLoadPriority.Num; i++)  //每次循环都是从最高优先级开始的(0)
            {
                List <AsyncLoadDataItem> asyncDataItemList = m_asyncLoadItemListArray[i];
                if (asyncDataItemList == null || asyncDataItemList.Count <= 0)
                {
                    continue;
                }
                if (m_asyncLoadItemListArray[(int)AsyncLoadPriority.High].Count > 0)
                {
                    i = (int)AsyncLoadPriority.High;
                }
                else if (m_asyncLoadItemListArray[(int)AsyncLoadPriority.Middile].Count > 0)
                {
                    i = (int)AsyncLoadPriority.Middile;
                }

                AsyncLoadDataItem asyncDataItem = asyncDataItemList[0];
                asyncDataItemList.Remove(asyncDataItem);

                Object obj = null;
                AssetBundleDataItem dataItem = null;
#if UNITY_EDITOR
                if (!GameRoot.m_UseAssetBundleInEditor)
                {
                    if (asyncDataItem.IsSprite)
                    {
                        obj = LoadABDataItemInEditorMode <Sprite>(asyncDataItem.Path);
                    }
                    else
                    {
                        obj = LoadABDataItemInEditorMode <Object>(asyncDataItem.Path);
                    }

                    //模拟异步加载
                    yield return(new WaitForSeconds(0.5f));

                    dataItem
                        = AssetBundleManager.Instance.GetABDataItem(asyncDataItem.Crc);
                }
#endif
                if (obj == null)
                {
                    dataItem = AssetBundleManager.Instance.LoadABDataItem(asyncDataItem.Crc);
                    AssetBundleRequest abRequest = null;
                    if (asyncDataItem.IsSprite)
                    {
                        abRequest = dataItem.AB.LoadAssetAsync <Sprite>(dataItem.AssetName);
                    }
                    else
                    {
                        abRequest = dataItem.AB.LoadAssetAsync(dataItem.AssetName);
                    }

                    yield return(abRequest);

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

                    preYieldTime = System.DateTime.Now.Ticks;
                }
                callBackList = asyncDataItem.CallBackList;

                //缓存dataitem
                CacheABDataItem(asyncDataItem.Path, ref dataItem, obj, callBackList.Count);

                //执行回调列表
                for (int j = 0; j < callBackList.Count; j++)
                {
                    AsyncLoadCallBack callBack = null;
                    callBack = callBackList[j];
                    if (callBack != null)
                    {
                        //不需要实例化资源的异步加载回调
                        if (callBack.DealFinish != null)
                        {
                            callBack.DealFinish(asyncDataItem.Path, obj, callBack.Param1, callBack.Param2, callBack.Param3);
                            callBack.DealFinish = null;
                        }

                        //实例化对象异步加载回调
                        if (callBack.ResGoDealFinish != null && callBack.resGo != null)
                        {
                            //执行这个回调会赋值resGo的abDataItem,(因为在协程里面才是加载dataItem的)
                            ResourceGameObject resGo = callBack.resGo;
                            resGo.ABDataItem = dataItem;
                            callBack.ResGoDealFinish(asyncDataItem.Path, resGo, resGo.Param1, resGo.Param2, resGo.Param3);
                            callBack.ResGoDealFinish = null;
                            resGo = null;
                        }

                        callBack.Reset();                      //重置
                        m_asyncCallBackPool.Recycle(callBack); //回收类对象
                    }
                }

                //清理,回收
                asyncDataItem.Reset();                           //重置
                m_asyncLoadingItemDic.Remove(asyncDataItem.Crc); //从正在加载dic中移除
                m_asyncDataItemPool.Recycle(asyncDataItem);      //回收类对象
                obj = null;
                callBackList.Clear();

                if (System.DateTime.Now.Ticks - preYieldTime > MAXASYNCLOADTIME)
                {
                    hadYield = true;
                    //等待一帧
                    yield return(null);

                    preYieldTime = System.DateTime.Now.Ticks;
                }
            }
            if (!hadYield && System.DateTime.Now.Ticks - preYieldTime > MAXASYNCLOADTIME)
            {
                preYieldTime = System.DateTime.Now.Ticks;
                yield return(null);
            }
        }
    }
コード例 #14
0
 /// <summary>
 /// 回收到对象池时减少ABDataItem的引用计数
 /// </summary>
 public int DecreaseResGoRefCount(ResourceGameObject resGo, int count = 1)
 {
     return(resGo != null?DecreaseRefCount(resGo.Crc, count) : 0);
 }