【Unity3d】【項目學習心得】從資源服務器下載資源(三)

 

【Unity3d】【項目學習心得】從資源服務器下載資源(三)


上一篇我們分析了 從資源服務器下載資源(二)  接下來我們繼續分析 LoadManager類。


當我們的任務下載完成後,我們需要對任務的委託進行回調到調用對象。

我們初步加入的委託有 complete、process、error ,接下來分別對這三個委託寫相應的回調。


[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. /// <summary>  
  2. ///  下載錯誤回調  
  3. /// </summary>  
  4. public void ErrorDelegateHandle(LoadRequest request) {  
  5.     if (request.errorFunction != null) {  
  6.         int count = request.errorFunction.GetInvocationList().GetLength(0);  
  7.         for (int i = 0; i < count; i++) {  
  8.             LoadRequest.ErrorDelegate errorFunc = (LoadRequest.ErrorDelegate)request.errorFunction.GetInvocationList()[i];  
  9.             try {  
  10.                 errorFunc.Invoke(request);  
  11.             } catch (Exception e) {  
  12.                 Debug.LogWarning("exception:" + e.Message);  
  13.             }  
  14.         }  
  15.     }  
  16. }  
  17.   
  18. /// <summary>  
  19. ///  下載進度回調  
  20. /// </summary>  
  21. public void ProcessDelegateHandle(LoadRequest request) {  
  22.     if (request.processFunction != null) {  
  23.         int count = request.processFunction.GetInvocationList().GetLength(0);  
  24.         for (int i = 0; i < count; i++) {  
  25.             LoadRequest.ProcessDelegate processFunc = (LoadRequest.ProcessDelegate)request.processFunction.GetInvocationList()[i];  
  26.             try {  
  27.                 processFunc.Invoke(request.wwwObject.progress, request.wwwObject.bytesDownloaded);  
  28.             } catch (Exception e) {  
  29.                 Debug.LogWarning("exception:" + e.Message);  
  30.             }  
  31.         }  
  32.     }  
  33. }  
  34.   
  35. /// <summary>  
  36. ///  任務下載完成回調  
  37. /// </summary>  
  38. /// <param name="request"></param>  
  39. /// <param name="param"></param>  
  40. public void CompleteDelegateHandle(LoadRequest request, LoadParam param) {  
  41.     if (request.completeFunction != null) {  
  42.         int count = request.completeFunction.GetInvocationList().GetLength(0);  
  43.         for (int i = 0; i < count; i++) {  
  44.             if (i < request.customParams.Count) {  
  45.                 param.param = request.customParams[i];  
  46.             }  
  47.             LoadRequest.DownCompleteDelegate completeFunc = (LoadRequest.DownCompleteDelegate)request.completeFunction.GetInvocationList()[i];  
  48.             try {  
  49.                 completeFunc.Invoke(param);  
  50.             } catch (Exception exception) {  
  51.                 Debug.LogWarning("exception:" + exception.Message);  
  52.             }  
  53.         }  
  54.     }  
  55. }  


1. 在上面我們注意到有一個陌生的類 LoadParam. 這個類是用來做什麼的呢?

很簡單,因爲我們下載完成後會進行存儲所有的下載結果,方便後續下載相同資源時可以馬上調用。所以我們需要專門的對象來存放。

我們把所有類型寫到一個類裏面,然後標註好該對象的對應URL、filetype。

如下:

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. /** 
  2.  * 任務下載的資源 
  3.  * create by chensh 2014.10.27 10:35 
  4.  */  
  5.   
  6. using UnityEngine;  
  7. using System.Collections;  
  8.   
  9.   
  10. namespace AssemblyCSharp {  
  11.     public class LoadParam {  
  12.         // 加載的文件類型  
  13.         public string fileType;  
  14.         // 加載的路徑  
  15.         public string url;  
  16.   
  17.         // 自定義參數  
  18.         public object param = null;  
  19.         // 圖片  
  20.         public Texture2D texture2D;  
  21.         // 文本  
  22.         public string text = "";  
  23.         // unity3d格式文件,目前針對場景打包的unity3d格式文件  
  24.         public AssetBundle assetBundle = null;  
  25.         // json文件  
  26.         public string jsonData;  
  27.         // 二進制文件  
  28.         public byte[] byteArr;  
  29.         // 音頻文件  
  30.         public AudioClip audioClip;  
  31.         // 模塊資源打包格式文件  
  32.         public UIAtlas uiAtlas;  
  33.         // fbx打包的文件對象  
  34.         public UnityEngine.Object mainAsset;  
  35.         // font文件  
  36.         public UIFont font;  
  37.          
  38.     }  
  39. }  


2. 此時我們需要一個函數。來解析下載完後的資源,並保存到 LoadParam 中。


[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. /// <summary>  
  2.     ///  解析下載內容  
  3.     /// </summary>  
  4.     public LoadParam ParseLoadParamFromLoadRequest(LoadRequest request) {  
  5.         LoadParam param = new LoadParam();  
  6.         param.url = request.requestURL;  
  7.         param.priority = request.priotiry; // 爲何param需要記錄優先級?  
  8.         param.fileType = request.fileType;  
  9.   
  10.         switch (request.fileType) {  
  11.             case LoadFileType.IMAGE:  
  12.                 try {  
  13.                     param.texture2D = request.wwwObject.texture;  
  14.                     param.texture2D.Compress(false);    // compress 有何影響  
  15.                 } catch (Exception exception) {  
  16.                     Debug.LogWarning("read texture2d error:" + request.requestURL +"\n" + exception.Message);  
  17.                 }  
  18.                 break;  
  19.             case LoadFileType.TXT:  
  20.                 try {  
  21.                     param.text = request.wwwObject.text;  
  22.                 } catch (Exception exception) {  
  23.                     Debug.LogWarning("read text error:" + request.requestURL + "\n" + exception.Message);  
  24.                 }  
  25.                 break;  
  26.             case LoadFileType.UNITY3D:  
  27.                 try {  
  28.                     if (request.wwwObject.assetBundle != null) {  
  29.                         param.assetBundle = request.wwwObject.assetBundle;  
  30.                     }  
  31.                 } catch (Exception exception) {  
  32.                     Debug.LogWarning("read assetBundle error:" + request.requestURL + "\n" + exception.Message);  
  33.                 }  
  34.                 break;  
  35.             case LoadFileType.MODULE_RESOURCE:  
  36.                 try {  
  37.                     UnityEngine.Object[] data = request.wwwObject.assetBundle.LoadAll();  
  38.                     int length = data.Length;  
  39.                     for (int i = 0; i < length; i++) {  
  40.                         if (data[i] is GameObject) {  
  41.                             param.uiAtlas = (data[i] as GameObject).GetComponent<UIAtlas>();  
  42.                             break;  
  43.                         }  
  44.                     }  
  45.                     request.wwwObject.assetBundle.Unload(false);  
  46.                 } catch (Exception exception) {  
  47.                     Debug.LogWarning("read uiatlas error:" + request.requestURL + "\n" + exception.Message);  
  48.                 }  
  49.                 break;  
  50.             case LoadFileType.JSON:  
  51.                 try {  
  52.                     param.jsonData = request.wwwObject.text.Trim();  
  53.                 } catch (Exception exception) {  
  54.                     Debug.LogWarning("read  json error:" + request.requestURL + "\n" + exception.Message);  
  55.                 }  
  56.                 break;  
  57.             case LoadFileType.FBX:  
  58.                 try {  
  59.                     param.mainAsset = request.wwwObject.assetBundle.mainAsset;  
  60.                 } catch (Exception exception) {  
  61.                     Debug.LogWarning("read  fbx error:" + request.requestURL + "\n" + exception.Message);  
  62.                 }  
  63.                 break;  
  64.             case LoadFileType.BINARY:  
  65.             case LoadFileType.BINARY_BG:  
  66.                 try {  
  67.                     param.byteArr = request.wwwObject.bytes;  
  68.                 } catch (Exception exception) {  
  69.                     Debug.LogWarning("read  binary error:" + request.requestURL + "\n" + exception.Message);  
  70.                 }  
  71.                 break;  
  72.             case LoadFileType.AUDIO:  
  73.                 try {  
  74.                     UnityEngine.Object[] data = request.wwwObject.assetBundle.LoadAll();  
  75.                     int length = data.Length;  
  76.                     for (int i = 0; i < length; i++) {  
  77.                         if (data[i] is AudioClip) {  
  78.                             param.audioClip = data[i] as AudioClip;  
  79.                             break;  
  80.                         }  
  81.                     }  
  82.                     request.wwwObject.assetBundle.Unload(false);  
  83.                 } catch (Exception exception) {  
  84.                     Debug.LogWarning("read audio error:" + request.requestURL + "\n" + exception.Message);  
  85.                 }  
  86.                 break;  
  87.             case LoadFileType.FONT:  
  88.                 try {  
  89.                     UnityEngine.Object[] data = request.wwwObject.assetBundle.LoadAll();  
  90.                     int length = data.Length;  
  91.                     for (int i = 0; i < length; i++) {  
  92.                         if (data[i] is UnityEngine.Transform) {  
  93.                             param.font = (data[i] as UnityEngine.Transform).GetComponent<UIFont>();  
  94.                             break;  
  95.                         }  
  96.                     }  
  97.                     request.wwwObject.assetBundle.Unload(false);  
  98.                 } catch (Exception exception) {  
  99.                     Debug.LogWarning("read  font error:" + request.requestURL + "\n" + exception.Message);  
  100.                 }  
  101.                 break;  
  102.         }  
  103.         return param;  
  104.     }  

3.我們發現,似乎還沒有對下載隊列進行檢測,即檢測WWW類下載的狀態。是已經下載完成了呢,還是下載出錯。

這個時候我們需要一個定時器。

每隔一定時間對下載隊列進行檢測,我們在構造函數那裏添加一個定時器。


[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public LoadManager() {  
  2.        Application.backgroundLoadingPriority = ThreadPriority.Low;  
  3.        // add timer to check download queue  
  4.        FrameTimerManager.getInstance().add(1, 0, CheckQueue);  
  5.    }  

其中的 CheckQueue() 函數是檢測函數。


[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. /// <summary>  
  2.     ///  定時器下,在每幀對下載隊列進行檢測  
  3.     ///  如果下載有問題,或者超時,則清除  
  4.     ///  如果下載完成,則解析下載結果,並進入completeDict中  
  5.     /// </summary>  
  6.     public void CheckQueue() {  
  7.         if (!isLoading) return;  
  8.         foreach (KeyValuePair<string, LoadRequest> pair in loadDict) {  
  9.             LoadRequest request = pair.Value;  
  10.             request.loadTotalFrames++;  
  11.             // deal error  
  12.             if ((request.wwwObject != null && request.wwwObject.error != null) || request.isTimeOut) {  
  13.                 if (request.requestURL.Contains(".apk") || request.requestURL.Contains(".ipa")) {  
  14.                     return;  
  15.                 }  
  16.                 request.alreadyDeal = true;  
  17.                 loadDict.Remove(request.requestURL);  
  18.                 ErrorDelegateHandle(request);  
  19.                 if (request.isTimeOut) {  
  20.                     Debug.LogWarning("Load time out:" + request.requestURL);  
  21.                 } else {  
  22.                     Debug.LogWarning("Load error:" + request.requestURL);  
  23.                 }  
  24.                 MoveRequestFromWaitDictToLoadDict();  
  25.                 break;  
  26.             }  
  27.   
  28.             //   
  29.             if (!request.alreadyDeal) {  
  30.                 ProcessDelegateHandle(request);  
  31.                 // if done  
  32.                 if (request.wwwObject != null && request.wwwObject.isDone) {  
  33.                     LoadParam param = ParseLoadParamFromLoadRequest(request);  
  34.                     if (request.fileType != LoadFileType.BINARY) {  
  35.                         completeDict.Add(request.requestURL, param);  
  36.                     }  
  37.                     //  
  38.                     CompleteDelegateHandle(request, param);  
  39.                     //  
  40.                     request.alreadyDeal = true;  
  41.                     loadDict.Remove(request.requestURL);  
  42.                     MoveRequestFromWaitDictToLoadDict();  
  43.                     break;  
  44.                 }  
  45.             }  
  46.   
  47.         }  
  48.     }  


至此,我們的LoadManager類即完成相應的功能。


轉載:http://blog.csdn.net/mad2man/article/details/40584039


發佈了6 篇原創文章 · 獲贊 127 · 訪問量 86萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章