您的位置:首页 > 移动开发 > Unity3D

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

2016-08-11 10:21 393 查看
 


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

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

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

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

[csharp] view
plain copy

 





/// <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。

如下:

[csharp] view
plain copy

 





/** 

 * 任务下载的资源 

 * 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 中。

[csharp] view
plain copy

 





/// <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类下载的状态。是已经下载完成了呢,还是下载出错。

这个时候我们需要一个定时器。

每隔一定时间对下载队列进行检测,我们在构造函数那里添加一个定时器。

[csharp] view
plain copy

 





public LoadManager() {  

       Application.backgroundLoadingPriority = ThreadPriority.Low;  

       // add timer to check download queue  

       FrameTimerManager.getInstance().add(1, 0, CheckQueue);  

   }  

其中的 CheckQueue() 函数是检测函数。

[csharp] view
plain copy

 





/// <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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐