游戏资源下载(2)——多文件加载并动态分配下载任务

多文件下载,把文件加入链表中,下载中和下载结束后的委托

 

限定数目5个

开始下载

        /// <summary>
        /// 下载多个文件
        /// </summary>
        /// <param name="lstUrl"></param>
        /// <param name="onUpdate"></param>
        /// <param name="onComplete"></param>
        internal void BeginDownloadMulit(LinkedList<string> lstUrl, BaseAction<int, int, ulong, ulong> onUpdate, BaseAction onComplete)
        {
            m_OnDownloadMulitUpdate = onUpdate;
            m_OnDownloadMulitComplete = onComplete;

            m_NeedDownloadList.Clear();
            m_DownloadMulitCurrSizeDic.Clear();

            m_DownloadMulitNeedCount = 0;
            m_DownloadMulitCurrCount = 0;

            m_DownloadMulitTotalSize = 0;
            m_DownloadMulitCurrSize = 0;

            //1.把需要下载的加入下载队列
            for (LinkedListNode<string> item = lstUrl.First; item != null; item = item.Next)
            {
                string url = item.Value;
                //下载的时候检测数据的合法性,能从Assetbunlle中拿到信息,说明是有效的
                AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url);
                if (entity != null)
                {
                    //文件的总大小是通过打包的时候计算出来的
                    m_DownloadMulitTotalSize += entity.Size;
                    m_DownloadMulitNeedCount++;
                    //加到需要下载的文件链表中
                    m_NeedDownloadList.AddLast(url);
                    //对应的url中已经下载的大小
                    m_DownloadMulitCurrSizeDic[url] = 0;
                }
                else
                {
                    GameEntry.LogError("无效资源包=>" + url);
                }
            }

            //下载器数量限定为5个,下载的时候占带宽,下载的时候要写入内存,性能卡顿
            int routineCount = Mathf.Min(GameEntry.Download.DownloadRoutineCount, m_DownloadMulitNeedCount);
            for (int i = 0; i < routineCount; i++)
            {
                //从池中取下载器
                DownloadRoutine routine = GameEntry.Pool.DequeueClassObject<DownloadRoutine>();
                //拿到url
                string url = m_NeedDownloadList.First.Value;
                //从链表中剔除掉
                AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url);
                //执行下载器的下载,这个回调是所有下载器共用一个回调
                routine.BeginDownload(url, entity, OnDownloadMulitUpdate, OnDownloadMulitComplete);
                //然后加入到下载器链表中
                m_DownloadRoutineList.AddLast(routine);

                m_NeedDownloadList.RemoveFirst();
            }
        }

 开始下载

 

 

       /// <summary>
    /// 开始下载,第二个参数的参数,地址,字节数,进度;第三个参数的参数,url和下载器
    /// </summary>
    /// <param name="url"></param>
    /// <param name="onUpdate"></param>
    /// <param name="onComplete"></param>
    public void BeginDownload(string url, AssetBundleInfoEntity assetBundleInfo, BaseAction<string, ulong, float> onUpdate, BaseAction<string, DownloadRoutine> onComplete)
    {
        m_CurrFileUrl = url;
        m_CurrAssetBundleInfo = assetBundleInfo;
        m_OnUpdate = onUpdate;
        m_OnComplete = onComplete;

        m_DownloadLocalFilePath = string.Format("{0}/{1}", GameEntry.Resource.LocalFilePath, m_CurrFileUrl);

        //如果本地已有目标文件, 则删除
        if (File.Exists(m_DownloadLocalFilePath)) File.Delete(m_DownloadLocalFilePath);

        //下载新版本的资源
        m_DownloadLocalFilePath = m_DownloadLocalFilePath + ".temp";
        if (File.Exists(m_DownloadLocalFilePath))
        {
            if (PlayerPrefs.HasKey(m_CurrFileUrl))
            {
                if (!PlayerPrefs.GetString(m_CurrFileUrl).Equals(assetBundleInfo.MD5, StringComparison.CurrentCultureIgnoreCase))
                {
                    //根据MD5判断 跟CDN上的MD5不一致则删除原文件重新下载
                    File.Delete(m_DownloadLocalFilePath);
                    BeginDownload();
                }
                else
                {
                    //断点续传_继续下载
                    m_FileStream = File.OpenWrite(m_DownloadLocalFilePath);
                    m_FileStream.Seek(0, SeekOrigin.End);
                    m_BeginPos = (uint)m_FileStream.Length;
                    Download(string.Format("{0}/{1}", GameEntry.Data.SysDataManager.CurrChannelConfig.RealSourceUrl, m_CurrFileUrl), m_BeginPos);
                }
            }
            else
            {
                //本地没有MD5记录,重新下载
                File.Delete(m_DownloadLocalFilePath);
                BeginDownload();
            }
        }
        else
        {
            BeginDownload();
        }
    }

    /// <summary>
    /// 从零下载
    /// </summary>
    private void BeginDownload()
    {
        string directory = Path.GetDirectoryName(m_DownloadLocalFilePath);
        if (!Directory.Exists(directory))
        {
            Directory.CreateDirectory(directory);
        }

        m_FileStream = new FileStream(m_DownloadLocalFilePath, FileMode.Create, FileAccess.Write);

        PlayerPrefs.SetString(m_CurrFileUrl, m_CurrAssetBundleInfo.MD5);
        Download(string.Format("{0}/{1}", GameEntry.Data.SysDataManager.CurrChannelConfig.RealSourceUrl, m_CurrFileUrl));
    }

    /// <summary>
    /// 从头下载下载
    /// </summary>
    /// <param name="url"></param>
    private void Download(string url)
    {
        m_UnityWebRequest = UnityWebRequest.Get(url);
        m_UnityWebRequest.SendWebRequest();
    }

下载中

        /// <summary>
        /// 多文件下载中的委托
        /// </summary>
        /// <param name="url"></param>
        /// <param name="currDownSize">当前的文件已经下载的大小</param>
        /// <param name="progress"></param>
        private void OnDownloadMulitUpdate(string url, ulong currDownSize, float progress)
        {
            m_DownloadMulitCurrSizeDic[url] = currDownSize;

            ulong currSize = 0;

            //计算所有文件下载的大小,循环字典然后累加
            var enumerator = m_DownloadMulitCurrSizeDic.GetEnumerator();
            while (enumerator.MoveNext())
            {
                currSize += enumerator.Current.Value;
            }

            m_DownloadMulitCurrSize = currSize;

            if (m_DownloadMulitCurrSize > m_DownloadMulitTotalSize) m_DownloadMulitCurrSize = m_DownloadMulitTotalSize;


            if (m_OnDownloadMulitUpdate != null)
            {
                //更新当前数量,总数量,当前大小总大小
                m_OnDownloadMulitUpdate(m_DownloadMulitCurrCount, m_DownloadMulitNeedCount, m_DownloadMulitCurrSize, m_DownloadMulitTotalSize);
            }
        }

下载完之后的回调

 

        private void OnDownloadMulitComplete(string fileUrl, DownloadRoutine routine)
        {
            //检查需要加载的文件列表中是否有要下载的数量
            if (m_NeedDownloadList.Count > 0)
            {
                //让下载器继续工作
                string url = m_NeedDownloadList.First.Value;

                AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url);
                routine.BeginDownload(url, entity, OnDownloadMulitUpdate, OnDownloadMulitComplete);

                m_NeedDownloadList.RemoveFirst();
            }
            else
            {
                //没有需要下载的了,下载器从下载列表中移除并回池
                m_DownloadRoutineList.Remove(routine);
                GameEntry.Pool.EnqueueClassObject(routine);
            }

            //下载数量++
            m_DownloadMulitCurrCount++;

            //更新下载数量
            if (m_OnDownloadMulitUpdate != null)
            {
                m_OnDownloadMulitUpdate(m_DownloadMulitCurrCount, m_DownloadMulitNeedCount, m_DownloadMulitCurrSize, m_DownloadMulitTotalSize);
            }
                

            //当前下载数量=总数量
            if (m_DownloadMulitCurrCount == m_DownloadMulitNeedCount)
            {
                m_DownloadMulitCurrSize = m_DownloadMulitTotalSize;
                //执行全部下载完毕的委托
                if (m_OnDownloadMulitUpdate != null)
                {
                    //所有文件下载完毕,最后一次执行更新委托
                    m_OnDownloadMulitUpdate(m_DownloadMulitCurrCount, m_DownloadMulitNeedCount, m_DownloadMulitCurrSize, m_DownloadMulitTotalSize);
                }

                if (m_OnDownloadMulitComplete != null) m_OnDownloadMulitComplete();
                //Debug.LogError("所有资源下载完毕!!!");
            }
        }

 

生成版本文件的时候修改为ulong.

也修改为ulong

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值