【Unity3d】【프로젝트 학습 소감】자원 서버에서 자원 다운로드(3)

11043 단어
마지막으로 자원 서버에서 자원을 다운로드하는 것을 분석했습니다.
우리의 작업 다운로드가 끝난 후, 우리는 작업의 의뢰를 호출 대상으로 되돌려야 한다.
우리가 초보적으로 가입한 의뢰는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 +"
" + exception.Message); } break; case LoadFileType.TXT: try { param.text = request.wwwObject.text; } catch (Exception exception) { Debug.LogWarning("read text error:" + request.requestURL + "
" + 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 + "
" + 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 + "
" + exception.Message); } break; case LoadFileType.JSON: try { param.jsonData = request.wwwObject.text.Trim(); } catch (Exception exception) { Debug.LogWarning("read json error:" + request.requestURL + "
" + exception.Message); } break; case LoadFileType.FBX: try { param.mainAsset = request.wwwObject.assetBundle.mainAsset; } catch (Exception exception) { Debug.LogWarning("read fbx error:" + request.requestURL + "
" + 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 + "
" + 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 + "
" + 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 + "
" + 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 클래스는 상응하는 기능을 완성하게 되었다.

좋은 웹페이지 즐겨찾기