上一篇我們分析了 從資源服務器下載資源(二) 接下來我們繼續分析 LoadManager類。
當我們的任務下載完成後,我們需要對任務的委託進行回調到調用對象。
我們初步加入的委託有 complete、process、error ,接下來分別對這三個委託寫相應的回調。
- /// <summary>
- /// 下載錯誤回調
- /// </summary>
- public void ErrorDelegateHandle(LoadRequest request) {
- if (request.errorFunction != null) {
- int count = request.errorFunction.GetInvocationList().GetLength(0);
- for (int i = 0; i < count; i++) {
- LoadRequest.ErrorDelegate errorFunc = (LoadRequest.ErrorDelegate)request.errorFunction.GetInvocationList()[i];
- try {
- errorFunc.Invoke(request);
- } catch (Exception e) {
- Debug.LogWarning("exception:" + e.Message);
- }
- }
- }
- }
- /// <summary>
- /// 下載進度回調
- /// </summary>
- public void ProcessDelegateHandle(LoadRequest request) {
- if (request.processFunction != null) {
- int count = request.processFunction.GetInvocationList().GetLength(0);
- for (int i = 0; i < count; i++) {
- LoadRequest.ProcessDelegate processFunc = (LoadRequest.ProcessDelegate)request.processFunction.GetInvocationList()[i];
- try {
- processFunc.Invoke(request.wwwObject.progress, request.wwwObject.bytesDownloaded);
- } catch (Exception e) {
- Debug.LogWarning("exception:" + e.Message);
- }
- }
- }
- }
- /// <summary>
- /// 任務下載完成回調
- /// </summary>
- /// <param name="request"></param>
- /// <param name="param"></param>
- public void CompleteDelegateHandle(LoadRequest request, LoadParam param) {
- if (request.completeFunction != null) {
- int count = request.completeFunction.GetInvocationList().GetLength(0);
- for (int i = 0; i < count; i++) {
- if (i < request.customParams.Count) {
- param.param = request.customParams[i];
- }
- LoadRequest.DownCompleteDelegate completeFunc = (LoadRequest.DownCompleteDelegate)request.completeFunction.GetInvocationList()[i];
- try {
- completeFunc.Invoke(param);
- } catch (Exception exception) {
- Debug.LogWarning("exception:" + exception.Message);
- }
- }
- }
- }
1. 在上面我們注意到有一個陌生的類 LoadParam. 這個類是用來做什麼的呢?
很簡單,因爲我們下載完成後會進行存儲所有的下載結果,方便後續下載相同資源時可以馬上調用。所以我們需要專門的對象來存放。
我們把所有類型寫到一個類裏面,然後標註好該對象的對應URL、filetype。
如下:
- /**
- * 任務下載的資源
- * create by chensh 2014.10.27 10:35
- */
- using UnityEngine;
- using System.Collections;
- namespace AssemblyCSharp {
- public class LoadParam {
- // 加載的文件類型
- public string fileType;
- // 加載的路徑
- public string url;
- // 自定義參數
- public object param = null;
- // 圖片
- public Texture2D texture2D;
- // 文本
- public string text = "";
- // unity3d格式文件,目前針對場景打包的unity3d格式文件
- public AssetBundle assetBundle = null;
- // json文件
- public string jsonData;
- // 二進制文件
- public byte[] byteArr;
- // 音頻文件
- public AudioClip audioClip;
- // 模塊資源打包格式文件
- public UIAtlas uiAtlas;
- // fbx打包的文件對象
- public UnityEngine.Object mainAsset;
- // font文件
- public UIFont font;
- }
- }
2. 此時我們需要一個函數。來解析下載完後的資源,並保存到 LoadParam 中。
- /// <summary>
- /// 解析下載內容
- /// </summary>
- public LoadParam ParseLoadParamFromLoadRequest(LoadRequest request) {
- LoadParam param = new LoadParam();
- param.url = request.requestURL;
- param.priority = request.priotiry; // 爲何param需要記錄優先級?
- param.fileType = request.fileType;
- switch (request.fileType) {
- case LoadFileType.IMAGE:
- try {
- param.texture2D = request.wwwObject.texture;
- param.texture2D.Compress(false); // compress 有何影響
- } catch (Exception exception) {
- Debug.LogWarning("read texture2d error:" + request.requestURL +"\n" + exception.Message);
- }
- break;
- case LoadFileType.TXT:
- try {
- param.text = request.wwwObject.text;
- } catch (Exception exception) {
- Debug.LogWarning("read text error:" + request.requestURL + "\n" + exception.Message);
- }
- break;
- case LoadFileType.UNITY3D:
- try {
- if (request.wwwObject.assetBundle != null) {
- param.assetBundle = request.wwwObject.assetBundle;
- }
- } catch (Exception exception) {
- Debug.LogWarning("read assetBundle error:" + request.requestURL + "\n" + exception.Message);
- }
- break;
- case LoadFileType.MODULE_RESOURCE:
- try {
- UnityEngine.Object[] data = request.wwwObject.assetBundle.LoadAll();
- int length = data.Length;
- for (int i = 0; i < length; i++) {
- if (data[i] is GameObject) {
- param.uiAtlas = (data[i] as GameObject).GetComponent<UIAtlas>();
- break;
- }
- }
- request.wwwObject.assetBundle.Unload(false);
- } catch (Exception exception) {
- Debug.LogWarning("read uiatlas error:" + request.requestURL + "\n" + exception.Message);
- }
- break;
- case LoadFileType.JSON:
- try {
- param.jsonData = request.wwwObject.text.Trim();
- } catch (Exception exception) {
- Debug.LogWarning("read json error:" + request.requestURL + "\n" + exception.Message);
- }
- break;
- case LoadFileType.FBX:
- try {
- param.mainAsset = request.wwwObject.assetBundle.mainAsset;
- } catch (Exception exception) {
- Debug.LogWarning("read fbx error:" + request.requestURL + "\n" + exception.Message);
- }
- break;
- case LoadFileType.BINARY:
- case LoadFileType.BINARY_BG:
- try {
- param.byteArr = request.wwwObject.bytes;
- } catch (Exception exception) {
- Debug.LogWarning("read binary error:" + request.requestURL + "\n" + exception.Message);
- }
- break;
- case LoadFileType.AUDIO:
- try {
- UnityEngine.Object[] data = request.wwwObject.assetBundle.LoadAll();
- int length = data.Length;
- for (int i = 0; i < length; i++) {
- if (data[i] is AudioClip) {
- param.audioClip = data[i] as AudioClip;
- break;
- }
- }
- request.wwwObject.assetBundle.Unload(false);
- } catch (Exception exception) {
- Debug.LogWarning("read audio error:" + request.requestURL + "\n" + exception.Message);
- }
- break;
- case LoadFileType.FONT:
- try {
- UnityEngine.Object[] data = request.wwwObject.assetBundle.LoadAll();
- int length = data.Length;
- for (int i = 0; i < length; i++) {
- if (data[i] is UnityEngine.Transform) {
- param.font = (data[i] as UnityEngine.Transform).GetComponent<UIFont>();
- break;
- }
- }
- request.wwwObject.assetBundle.Unload(false);
- } catch (Exception exception) {
- Debug.LogWarning("read font error:" + request.requestURL + "\n" + exception.Message);
- }
- break;
- }
- return param;
- }
3.我們發現,似乎還沒有對下載隊列進行檢測,即檢測WWW類下載的狀態。是已經下載完成了呢,還是下載出錯。
這個時候我們需要一個定時器。
每隔一定時間對下載隊列進行檢測,我們在構造函數那裏添加一個定時器。
- public LoadManager() {
- Application.backgroundLoadingPriority = ThreadPriority.Low;
- // add timer to check download queue
- FrameTimerManager.getInstance().add(1, 0, CheckQueue);
- }
其中的 CheckQueue() 函數是檢測函數。
- /// <summary>
- /// 定時器下,在每幀對下載隊列進行檢測
- /// 如果下載有問題,或者超時,則清除
- /// 如果下載完成,則解析下載結果,並進入completeDict中
- /// </summary>
- public void CheckQueue() {
- if (!isLoading) return;
- foreach (KeyValuePair<string, LoadRequest> pair in loadDict) {
- LoadRequest request = pair.Value;
- request.loadTotalFrames++;
- // deal error
- if ((request.wwwObject != null && request.wwwObject.error != null) || request.isTimeOut) {
- if (request.requestURL.Contains(".apk") || request.requestURL.Contains(".ipa")) {
- return;
- }
- request.alreadyDeal = true;
- loadDict.Remove(request.requestURL);
- ErrorDelegateHandle(request);
- if (request.isTimeOut) {
- Debug.LogWarning("Load time out:" + request.requestURL);
- } else {
- Debug.LogWarning("Load error:" + request.requestURL);
- }
- MoveRequestFromWaitDictToLoadDict();
- break;
- }
- //
- if (!request.alreadyDeal) {
- ProcessDelegateHandle(request);
- // if done
- if (request.wwwObject != null && request.wwwObject.isDone) {
- LoadParam param = ParseLoadParamFromLoadRequest(request);
- if (request.fileType != LoadFileType.BINARY) {
- completeDict.Add(request.requestURL, param);
- }
- //
- CompleteDelegateHandle(request, param);
- //
- request.alreadyDeal = true;
- loadDict.Remove(request.requestURL);
- MoveRequestFromWaitDictToLoadDict();
- break;
- }
- }
- }
- }
至此,我們的LoadManager類即完成相應的功能。
轉載:http://blog.csdn.net/mad2man/article/details/40584039