【Unity3d】【项目学习心得】从资源服务器下载资源(三)

来源:互联网 发布:平面图纸设计软件 编辑:程序博客网 时间:2024/05/17 07:02

上一篇我们分析了 从资源服务器下载资源(二)  接下来我们继续分析 LoadManager类。


当我们的任务下载完成后,我们需要对任务的委托进行回调到调用对象。

我们初步加入的委托有 complete、process、error ,接下来分别对这三个委托写相应的回调。


[csharp] view plaincopy在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 plaincopy在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 plaincopy在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 plaincopy在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 plaincopy在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类即完成相应的功能。


1 0
原创粉丝点击