天天看點

unity 資源熱更新+顯示進度條:根據uri下資源

實作傳入uri,下載下傳對應的資源,并且能支援多個uri的下載下傳

例如:

List<string> listUri = new List<string>();
        List<string> listToPath = new List<string>();
        listUri.Add(AppConst.WebUrlVideo + "/2.mp4");
        listToPath.Add(AppConst.DataPath + "/2.mp4");

        listUri.Add(AppConst.WebUrlVideo + "/3.mp4");
        listToPath.Add(AppConst.DataPath + "/3.mp4");
        DownMgr.Instance.DownResMulti(listUri, listToPath);      

下載下傳2個視訊,

實作效果

unity 資源熱更新+顯示進度條:根據uri下資源
unity 資源熱更新+顯示進度條:根據uri下資源

DownMgr.cs 下載下傳管理器

public void DownResMulti(List<string> listUri,List<string> listToPath,UnityEvent onDownOk = null)
    {
        DataMgr.m_isMultiDown = true;
        StartCoroutine(YieldDownResMulti(listUri, listToPath, onDownOk));
    }

    IEnumerator YieldDownResMulti(List<string> listUri,List<string> listToPath,UnityEvent onDownOk = null)
    {
        long countLength = 0;
        int cnt = 0;
        for (int i = 0; i < listUri.Count; i++)
        {
            System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(listUri[i]);
            request.Method = "HEAD";
            countLength += request.GetResponse().ContentLength;
            cnt++;
        }

        PrecentMgr.m_instance.m_totalLen = countLength;
        Debug.Log("總下載下傳量:" + countLength);
        Debug.Log("下載下傳個數:" + cnt);

        for (int i = 0; i < listUri.Count; i++)
        {
            BeginDownload(listUri[i], listToPath[i]);
            while( !(IsDownOK(listToPath[i])))
            {
                yield return new WaitForEndOfFrame();
            }
        }
        yield return new WaitForEndOfFrame();
        if (onDownOk != null)
            onDownOk.Invoke();
    }
    
   void BeginDownload(string url, string file)
    {     //線程下載下傳
        object[] param = new object[2] { url, file };

        ThreadEvent ev = new ThreadEvent();
        ev.Key = NotiConst.UPDATE_DOWNLOAD;
        ev.evParams.AddRange(param);
        ThreadManager.Instance.AddEvent(ev, OnThreadCompleted);   //線程下載下傳
    }

    void OnThreadCompleted(NotiData data)
    {
        switch (data.evName)
        {
            case NotiConst.UPDATE_EXTRACT:  //解壓一個完成
                                            //
                break;
            case NotiConst.UPDATE_DOWNLOAD: //下載下傳一個完成
                downloadFiles.Add(data.evParam.ToString());
                break;
        }
    }

    /// <summary>
    /// 是否下載下傳完成
    /// </summary>
    bool IsDownOK(string file)
    {
        return downloadFiles.Contains(file);
    }      

1.周遊uri,使用System.Net.HttpWebRequest得到下載下傳的總量

2.放入線程中進行依次下載下傳,(下載下傳完一個再下載下傳另一個)

3.全部下載下傳完執行UnityEvent事件

ThreadManager.cs 下載下傳線程

/// <summary>
    /// 下載下傳檔案
    /// </summary>
    void OnDownloadFile(List<object> evParams) {
        string url = evParams[0].ToString();    
        currDownFile = evParams[1].ToString();

        using (WebClient client = new WebClient()) {
            sw.Start();
            client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
            client.DownloadFileAsync(new System.Uri(url), currDownFile);
        }
    }

    private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        DataMgr.m_downCur += (e.BytesReceived - m_lastDown);
        m_lastDown = e.BytesReceived;
        string value = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
        
        if (DataMgr.m_isMultiDown == false)
        {
            //下載下傳的總量
            PrecentData preData = new PrecentData();
            preData.total = string.Format("{0} MB / {1} MB", (e.BytesReceived / 1024d / 1024d).ToString("0.00"), (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));
            preData.precent = (float)e.BytesReceived / (float)e.TotalBytesToReceive;

            preData.speed = value;

            Loom.QueueOnMainThread((param) =>
          {
              NotificationCenter.Get().ObjDispatchEvent(KEventKey.m_evDownload, preData);
          }, null);
        }
        else if (DataMgr.m_isMultiDown == true)
        {
            Loom.QueueOnMainThread((param) =>
           {
               PrecentMgr.m_instance.UpdateMultiDown(value);
           }, null);
        }
        //正在下載下傳顯示進度
        //NotiData data = new NotiData(NotiConst.UPDATE_PROGRESS, value);
        //if (m_SyncEvent != null) m_SyncEvent(data);

        //下載下傳一個完成
        if (e.ProgressPercentage == 100 && e.BytesReceived == e.TotalBytesToReceive) {
            sw.Reset();
            m_lastDown = 0;
            NotiData data = new NotiData(NotiConst.UPDATE_DOWNLOAD, currDownFile);
            if (m_SyncEvent != null) m_SyncEvent(data);
        }
    }      

1.線程中每次取下載下傳隊列中的隊頭進行下載下傳

2.使用WebClient得到目前下載下傳檔案的資訊,包括目前下載下傳速度,每一時刻下載下傳量(傳遞給ui顯示)

3.當目前檔案下載下傳完成時調用委托m_SyncEvent,告訴DownMgr此檔案下載下傳完,進行下一個下載下傳uri的循環

PrecentMgr.cs 進度條顯示

public void UpdateMultiDown(string speed)
    {
        float precent = (float)DataMgr.m_downCur / (float)m_totalLen;
        m_imgPrecent.fillAmount = precent;
        string sPrecent = string.Format("{0} MB / {1} MB", (DataMgr.m_downCur / 1024d / 1024d).ToString("0.00"), (m_totalLen / 1024d / 1024d).ToString("0.00"));
        m_textSpeed.text = speed;
        m_textPrecent.text = sPrecent;
        if (precent >= 1.0f)
        {
            Destroy(gameObject);
        }
    }      

繼續閱讀