Unity3D資源異步加載(一)——圖片、音視頻資源加載

這幾天一直作優化的事情,對於資源這一塊優化,資源異步加載做爲首選,因2018以後版本中棄用了WWW請求,因此今天咱們以UnityWebRequest 請求方式介紹,基本上是一個整理。json

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class ResourceLoad : MonoBehaviour
{
    /// <summary>
    /// 單例
    /// </summary>
    private static ResourceLoad _instance = null;
    public static ResourceLoad Instance {
        get {

            if(null == _instance)
            {
                GameObject singleton = (GameObject)UnityEngine.Object.FindObjectOfType(typeof(GameObject));
                if(null == singleton)
                {
                    singleton = new GameObject("Singleton");
                    DontDestroyOnLoad(singleton);
                }

                _instance = singleton.GetComponent<ResourceLoad>();
                if (null == _instance)
                {
                    _instance = singleton.AddComponent<ResourceLoad>();
                }
            }

            return _instance;
        }
    }

    /*UnityWebRequests處理與Web服務器的HTTP通訊流。
     * 其餘對象-特別是DownloadHandler和UploadHandler-分別控制數據的下載和上傳。
     * 爲了方便起見,提供了一組靜態函數。這些將返回爲許多常見用例正確配置的UnityWebRequest對象。請參閱: Get,Post,Put,GetTexture。
     * 能夠對下面屬性瞭解
     * responseCode  服務器返回的數字HTTP響應代碼,例如200、404或500。(只讀)
     * timeout   設置UnityWebRequest以嘗試在超時秒數過去後停止。
     * downloadProgress     返回介於0.0和1.0之間的浮點值,指示從服務器下載正文數據的進度。(只讀)
     * 返回介於0.0和1.0之間的浮點值,指示將主體數據上傳到服務器的進度。
     * useHttpContinue  肯定此UnityWebRequest是否在其傳出請求標頭中包含Expect:100-Continue。(默認值:true)。
     * SendWebRequest   開始與遠程服務器通訊。
     * SetRequestHeader 將HTTP請求標頭設置爲自定義值。
     * Head Creates a UnityWebRequest configured to send a HTTP HEAD request.
     */

    #region--//對請求分裝
     /// <summary>
     /// get請求
     /// </summary>
     /// <param name="url"></param>
     /// <param name="actionResult"></param>
     public void WebquestGet(string url, System.Action<bool, string> actionResult)
     {
        StartCoroutine(_Get(url, actionResult));
    }
    /// <summary>
    /// Sprite請求
    /// </summary>
    /// <param name="url"></param>
    /// <param name="actionResult"></param>
     public void WebquestGet(string url, System.Action<bool, string, Sprite> actionResult)
     {
        StartCoroutine(_GetTexture(url, actionResult));
     }

    // .
    // .
    // .
    // . 省略

    #endregion

    #region --- 網絡請求
    /// <summary>
    /// GET請求
    /// </summary>
    /// <param name="url">請求地址</param>
    /// <param name="action">請求發起後處理回調結果的委託</param>
    /// <returns></returns>
    IEnumerator _Get(string url, System.Action<bool, string> actionResult)
    {
        using (UnityWebRequest quest = UnityWebRequest.Get(url))
        {
            yield return quest.SendWebRequest();
            string msg = "";
            if (!(quest.isNetworkError || quest.isHttpError))
            {
                msg = quest.downloadHandler.text;
            }
            else
            {
                msg = quest.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke(quest.isHttpError, msg);
            }
        }
    }

    /// <summary>
    /// 請求文件byte
    /// </summary>
    /// <param name="url"></param>
    /// <param name="action">請求發起後處理回調結果的委託,處理請求結果的byte數組</param>
    /// <returns></returns>
    IEnumerator _GetBytes(string url, System.Action<bool, string, byte[]> actionResult)
    {

        using (UnityWebRequest quest = new UnityWebRequest(url))
        {
            DownloadHandlerFile downloadFile = new DownloadHandlerFile(url);
            quest.downloadHandler = downloadFile;
            yield return quest.SendWebRequest();
            byte[] bytes = null;
            string text = null;
            if (!(quest.isNetworkError || quest.isHttpError))
            {
                bytes = downloadFile.data;
            }
            else
            {
                text = quest.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke((quest.isNetworkError || quest.isHttpError), text, bytes);
            }
        }
    }

    /// <summary>
    /// 請求Sprite和圖片
    /// </summary>
    /// <param name="url">圖片地址'</param>
    /// <param name="action">請求發起後處理回調結果的委託,處理請求結果的圖片</param>
    /// <returns></returns>
    IEnumerator _GetTexture(string url, System.Action<bool, string, Sprite> actionResult)
    {
        using (UnityWebRequest quest = UnityWebRequestTexture.GetTexture(url)) // 或者直接用 new UnityWebRequest(url)
        {
            //DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true);
            //quest.downloadHandler = downloadTexture;
            yield return quest.SendWebRequest();
            string text = null;
            Sprite sprite = null;

            if (!(quest.isNetworkError || quest.isHttpError))
            {
                Texture2D texture = DownloadHandlerTexture.GetContent(quest); //downloadTexture.texture;
                sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));

            }
            else
            {
                text = quest.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke((quest.isNetworkError || quest.isHttpError), text, sprite);
            }
        }
    }

    /// <summary>
    /// 請求服務器地址上的音效
    /// </summary>
    /// <param name="url">沒有音頻地址</param>
    /// <param name="actionResult">請求發起後處理回調結果的委託,處理請求結果的MovieTexture</param>
    /// <param name="audioType">音效類型</param>
    /// <returns></returns>
    IEnumerator _GetAudioClip(string url, System.Action<bool, string, AudioClip> actionResult, AudioType audioType = AudioType.WAV)
    {
        using (UnityWebRequest quest = UnityWebRequest.Get(url))
        {
            DownloadHandlerAudioClip downloadAudioClip = new DownloadHandlerAudioClip(url, audioType);
            quest.downloadHandler = downloadAudioClip;
            yield return quest.SendWebRequest();
            AudioClip audioClip = null;
            string text = null;
            if (!(quest.isNetworkError || quest.isHttpError))
            {
                audioClip = downloadAudioClip.audioClip;
            }
            else
            {
                text = quest.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke((quest.isNetworkError || quest.isHttpError), text, audioClip);
            }
        }
    }

    /// <summary>
    /// 向服務器提交post請求
    /// </summary>
    /// <param name="url">服務器請求目標地址</param>
    /// <param name="formData">form表單參數</param>
    /// <returns></returns>
    IEnumerator _Post(string url, string formData, System.Action<bool, string> actionResult)
    {

        using (UnityWebRequest quest = UnityWebRequest.Post(url, formData))
        {
            //發送數據
            setWebRequest(quest, formData);
            yield return quest.SendWebRequest();
            string text = "";
            if (!(quest.isNetworkError || quest.isHttpError))
            {
                text = quest.downloadHandler.text;
            }
            else
            {
                text = quest.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke(quest.isHttpError, text);
            }
        }
    }

    /// <summary>
    /// 設置表頭和發送信息
    /// </summary>
    /// <param name="quest"></param>
    /// <param name="info"></param>
    void setWebRequest(UnityWebRequest quest, string info)
     {
        //設置發送表頭信息
        quest.SetRequestHeader("Content-Type", "application/json");

        //設置發送的信息
        Object objectInfo = null;//(設置info 類結構對象信息)
        string jsonId = JsonUtility.ToJson(objectInfo);
        byte[] wForm = System.Text.Encoding.UTF8.GetBytes(jsonId);
        quest.uploadHandler = new UploadHandlerRaw(wForm);
        quest.downloadHandler = new DownloadHandlerBuffer();

        //或者
        //List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        //formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
        //formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));
    }

    #endregion

}
相關文章
相關標籤/搜索