什么是UnityWebRequest類
UnityWebRequest
?是 Unity 引擎中用于處理網絡請求的一個強大類,它可以讓你在 Unity 項目里方便地與網絡資源進行交互,像發送 HTTP 請求、下載文件等操作都能實現。下面會詳細介紹?UnityWebRequest
?的相關內容。
UnityWebRequest中的常用操作
? ? ? ? //1.使用Get獲取文本或二進制數據
? ? ? ? //2.使用Get獲取紋理數據
? ? ? ? //3.使用Get獲取AB包數據
? ? ? ? //4.使用Post請求發送數據
? ? ? ? //5.使用Put請求上傳數據
Get操作
#region 知識點三 Get獲取操作//1.獲取文本或2進制StartCoroutine(DownLoadText());//2.獲取紋理StartCoroutine(DownLoadImage());//3.獲取AB包StartCoroutine(DownLoadAB());#endregion }IEnumerator DownLoadText(){UnityWebRequest req = UnityWebRequest.Get("http://172.41.2.6/HTTP_Server/");//就會等待服務器端響應后 斷開連接后 再繼續執行后面的內容yield return req.SendWebRequest();//如果處理成功,結果就是成功枚舉if(req.result ==UnityWebRequest.Result.Success){//文本 字符串print(req.downloadHandler.text);//字節數組byte[] bytes = req.downloadHandler.data;}else{print("獲取失敗:" + req.result + req.error + req.responseCode);}}IEnumerator DownLoadImage(){UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/測試圖片.png");yield return req.SendWebRequest();if(req.result ==UnityWebRequest.Result.Success ){//(req.downloadHandler as DownloadHandlerTexture).texture;//DownloadHandlerTexture.GetContent(req);//image.texture =(req.downloadHandler as DownloadHandlerTexture).texture;image.texture = DownloadHandlerTexture.GetContent(req);}else{print("獲取失敗" + req.error + req.result + req.responseCode);}}IEnumerator DownLoadAB(){UnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle("http://172.41.2.6/HTTP_Server/lua");//yield return req.SendWebRequest();req.SendWebRequest();while(!req .isDone ){print(req.downloadProgress);print(req.downloadedBytes);yield return null;}if(req .result ==UnityWebRequest.Result.Success ){//AssetBundle ab=(req.downloadHandler as DownloadHandlerAssetBundle).assetBundle;AssetBundle ab = DownloadHandlerAssetBundle.GetContent(req);}elseprint("獲取失敗" + req.error + req.result + req.responseCode);}
Post和Put操作
上傳數據相關類
#region 知識點一 上傳相關數據類//父接口//IMultipartFromSection//數據相關類都繼承該接口//我們可以用父類裝子類List<IMultipartFormSection> dataList = new List<IMultipartFormSection>();//子類數據//MutipartFromDataSection//1.二進制字節數組dataList.Add(new MultipartFormDataSection(Encoding.UTF8.GetBytes("23399ffs")));//2.字符串dataList.Add(new MultipartFormDataSection("sjfjgnafd"));//3.參數名、參數值(字節數組、字符串)、編碼類型、資源類型(常用)dataList.Add(new MultipartFormDataSection("Name", "DamnF", Encoding.UTF8, "application/..."));dataList.Add(new MultipartFormDataSection("msg", new byte[1024], "appl...."));//MultipartFromFileSection//1.字節數組dataList.Add(new MultipartFormFileSection(File.ReadAllBytes(Application.streamingAssetsPath + "/test.png")));//2.文件名、字節數組(常用)dataList.Add(new MultipartFormFileSection("上傳的文件.png", File.ReadAllBytes(Application.streamingAssetsPath + "/test.png")));//3.字符串數據、文件名(常用)dataList.Add(new MultipartFormFileSection("2r0402099", "text.txt"));//4.字符串數據、編碼格式、文件名(常用)dataList.Add(new MultipartFormFileSection("299ffjej3", Encoding.UTF8, "test.txt"));//5.表單名、字節數組、文件名、文件類型dataList.Add(new MultipartFormFileSection("file", new byte[1024], "test.txt", ""));//6.表單名、字符串數據、編碼格式、文件名dataList.Add(new MultipartFormFileSection("file", "dggt4hdsgg", Encoding .UTF8, ""));#endregion
Post和Put
#region 知識點二 Post發送相關StartCoroutine(UpLoad());#endregion#region 知識點三 Put上傳相關//注意:Put請求類型不是所有的web服務器都認,必須要服務器處理該請求才能有響應#endregion }IEnumerator UpLoad(){//準備上傳的數據List<IMultipartFormSection> dataList = new List<IMultipartFormSection>();//鍵值對相關的 信息 字段數據dataList.Add(new MultipartFormDataSection("Name", "DamnF"));//PlayerMsg msg = new PlayerMsg();//dataList.Add(new MultipartFormDataSection("Msg", msg.Writing()));//添加一些上傳文件//傳2進制文件dataList.Add(new MultipartFormFileSection("TestTest124.png", File.ReadAllBytes(Application.streamingAssetsPath + "/test.png")));//傳文本文件dataList.Add(new MultipartFormFileSection("12444515", "Test123.txt"));UnityWebRequest req = UnityWebRequest.Post("http://172.41.2.6/HTTP_Server/",dataList);req.SendWebRequest();while (!req.isDone){print(req.uploadProgress);print(req.uploadedBytes);yield return null;}print(req.uploadProgress);print(req.uploadedBytes);if (req.result == UnityWebRequest.Result.Success){print("上傳成功");//req.downloadHandler.data;}elseprint("上傳失敗" + req.error + req.responseCode + req.result);}IEnumerator UpLoadPut(){UnityWebRequest req= UnityWebRequest.Put("http://172.41.2.6/HTTP_Server/", File.ReadAllBytes(Application.streamingAssetsPath + "/test.png"));yield return req.SendWebRequest();if(req.result ==UnityWebRequest.Result.Success ){print("上傳put成功");}else{}}
UnityWebRequest中的高級操作
#region 知識點一 UnityWebRequest高級操作指什么//高級操作是指讓你按照規則來實現更多的數據獲取、上傳的功能#endregion#region 知識點二 UnityWebRequest中更多的內容//目前已學的內容//UnityWebRequest req = UnityWebRequest.Get("");//UnityWebRequest req = UnityWebRequestTexture.GetTexture("");//UnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle("");//UnityWebRequest req = UnityWebRequest.Put();//UnityWebRequest req = UnityWebRequest.Post();//req.isDone//req.downloadProgress//req.downloadProgress //req.uploadedBytes//req.uploadProgress//req.SendWebRequest();//更多內容//1.構造函數UnityWebRequest req = new UnityWebRequest();//2.請求地址req.url = "服務器地址";//3.請求類型req.method = UnityWebRequest.kHttpVerbGET;//4.進度//req.downloadProgress//req.uploadProgress //5.超時設置//req.timeout=2000;//6.上傳、下載的字節數//req.uploadedBytes //req.downloadedBytes //7.重定向次數 設置為0表示不進行重定向 可以設置次數req.redirectLimit = 10;//8.狀態碼 結果 錯誤內容//req.result;//req.error;//req.responseCode;//9.下載、上傳處理對象//req.downloadHandler;//req.uploadHandler;#endregion #region 知識點三 自定義獲取數據DownloadHandler相關類//關鍵類://1.DownloadHandlerBuffer 用于簡單的數據存儲,得到對應的2進制數據//2.DownloadHandlerFile 用于下載文件并將文件保存到磁盤(內存占用少)//3.DownloasHandlerTexture 用于下載圖像//4.DownloadHandlerAssetBundle 用于提取AssetBundle//5.DownloadHandlerAudioClip 用于下載音頻文件//以上的類,其實是Unity幫我們實現好的,用于解析下載下來的數據的類//使用對應的類處理下載數據 它們就會在內部將下載好的數據處理為對應類型,方便我們使用//DownloadHandlerScript 是一個特殊的類 就本身而言 不會執行任何操作//但是此類可由用戶定義的類繼承。此類接收來自UnityWebRequest系統的回調//然后可以使用這些回調在數據從網絡到達時執行完全自定義的數據處理StartCoroutine(DownLoadTex());StartCoroutine(DownLoadAB());StartCoroutine(DownLoadAudioClip());#endregion}IEnumerator DownLoadTex(){UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/測試圖片.png", UnityWebRequest.kHttpVerbGET);//req.method = UnityWebRequest.kHttpVerbGET;//1.DownloadHandlerBufferDownloadHandlerBuffer bufferHandler = new DownloadHandlerBuffer();req.downloadHandler = bufferHandler;//2.DownloadHandlerFilereq.downloadHandler = new DownloadHandlerFile(Application.persistentDataPath + "/downloadfile.png");//3.DownloadHandlerTextureDownloadHandlerTexture handlerTexture = new DownloadHandlerTexture();req.downloadHandler = handlerTexture;yield return req.SendWebRequest();if(req.result ==UnityWebRequest.Result.Success ){//獲取字節數組//bufferHandler.data}else{print("獲取數據失敗" + req.result + req.error + req.responseCode);}}IEnumerator DownLoadAB(){UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/lua", UnityWebRequest.kHttpVerbGET);//第二個參數,需要已知校檢碼 才能進行比較 檢查完整性 如果不知道的話 只能傳0 不進行完整性檢查//所以一般 只有進行AB包熱更新時 服務器發送了 對應的 文件列表中 包含了 驗證碼才能進行檢查DownloadHandlerAssetBundle downloadHandlerAB = new DownloadHandlerAssetBundle(req.url, 0);req.downloadHandler = downloadHandlerAB;yield return req.SendWebRequest();if (req.result == UnityWebRequest.Result.Success){AssetBundle ab = downloadHandlerAB.assetBundle;print(ab.name);}else{print("獲取數據失敗" + req.result + req.error + req.responseCode);}}IEnumerator DownLoadAudioClip(){UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip("http://172.41.2.6/HTTP_Server/音效文件.mp3",AudioType.MPEG);yield return req.SendWebRequest();if (req.result == UnityWebRequest.Result.Success){AudioClip a= DownloadHandlerAudioClip .GetContent(req);}else{print("獲取數據失敗" + req.result + req.error + req.responseCode);}}IEnumerator DownLoadCustomHandler(){UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/測試圖片.png", UnityWebRequest.kHttpVerbGET);req.downloadHandler = new CustomDownLoadFileHandler(Application.persistentDataPath + "/CustomHandler.png");yield return req.SendWebRequest();if (req.result == UnityWebRequest.Result.Success){print("存儲本地成功");}else{print("獲取數據失敗" + req.result + req.error + req.responseCode);}}
自定義獲取數據處理
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;public class DownLoadHanderMsg :DownloadHandlerScript
{private BaseMsg msg;private int index = 0;private byte[] cacheBytes;public DownLoadHanderMsg ():base(){}public T GetMsg<T>()where T:BaseMsg{return msg as T;}protected override byte[] GetData(){return base.GetData();}protected override void ReceiveContentLengthHeader(ulong contentLength){base.ReceiveContentLengthHeader(contentLength);}protected override bool ReceiveData(byte[] data, int dataLength){data.CopyTo(cacheBytes, dataLength);index += dataLength;return true;}protected override void CompleteContent(){index = 0;int msgID = BitConverter.ToInt32(cacheBytes,index);index += 4;int msgLength = BitConverter.ToInt32(cacheBytes, index);index += 4;switch (msgID){case 1001:msg = new PlayerMsg();msg.Reading(cacheBytes, index);break;}if (msg == null){Debug.Log("對應ID" + msgID + "沒有處理");}elseDebug.Log("消息處理完畢");}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;public class Lesson34_E : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){}IEnumerator GetMsg(){UnityWebRequest req = new UnityWebRequest("Web服務器地址", UnityWebRequest.kHttpVerbPOST);DownLoadHanderMsg handlerMsg= new DownLoadHanderMsg();req.downloadHandler = handlerMsg;yield return req.SendWebRequest();if(req.result ==UnityWebRequest.Result.Success ){PlayerMsg msg = handlerMsg.GetMsg<PlayerMsg>();//使用消息對象,來進行邏輯處理}}// Update is called once per framevoid Update(){}
}
UnityWebRequest高級操作--上傳數據
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;public class Lesson35 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){#region UnityWebRequest高級操作--上傳數據//1.UploadHandlerRaw--用于上傳字節數組//2.UploadHandlerFile--用于上傳文件//其中重要的變量是//contentType 內容類型,如果不設置,模式是application/octet-stream 2進制流的形式//以上部分作為了解,實際開發并不常用#endregion}IEnumerator UpLoad(){UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/", UnityWebRequest.kHttpVerbPOST);//1.UploadHandlerRaw--用于上傳字節數組//byte[] bytes = Encoding.UTF8.GetBytes("23fe33h3h3h");//req.uploadHandler = new UploadHandlerRaw(bytes);req.uploadHandler.contentType = "類型/細分類型";//2.UploadHandlerFile--用于上傳文件req.uploadHandler = new UploadHandlerFile(Application.streamingAssetsPath + "/test.png");yield return req.SendWebRequest();print(req.result);}// Update is called once per framevoid Update(){}
}
將UnityWebRequest中的操作封裝到WWWMgr模塊中
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;public class WWWMgr : MonoBehaviour
{private static WWWMgr instance = new WWWMgr();public static WWWMgr Instance => instance;private string HTTP_SERVER_PATH = "http://172.41.2.6/HTTP_Server/";private void Awake(){instance = this;DontDestroyOnLoad(this.gameObject);}public void LoadRes<T>(string path, UnityAction<T> action) where T : class{StartCoroutine(LoadResAsync<T>(path, action));}private IEnumerator LoadResAsync<T>(string path, UnityAction<T> action) where T : class{WWW www = new WWW(path);yield return www;if (www.error == null){//根據T泛型的類型 決定使用哪種類型的資源 傳遞給外部if (typeof(T) == typeof(AssetBundle)){action?.Invoke(www.assetBundle as T);}else if (typeof(T) == typeof(Texture)){action?.Invoke(www.texture as T);}else if (typeof(T) == typeof(AudioClip)){action?.Invoke(www.GetAudioClip() as T);}else if (typeof(T) == typeof(string)){action?.Invoke(www.text as T);}else if (typeof(T) == typeof(byte[])){action?.Invoke(www.bytes as T);}}else{Debug.LogError("加載資源出錯了" + www.error);}}public void UnityWebRequestLoad<T>(string path,UnityAction <T>action,string localPath="",AudioType type=AudioType.MPEG )where T:class {StartCoroutine(UnityWebRequestLoadAsync<T>(path, action, localPath, type));}private IEnumerator UnityWebRequestLoadAsync<T>(string path, UnityAction<T> action, string localPath = "", AudioType type = AudioType.MPEG) where T:class {UnityWebRequest req = new UnityWebRequest(path, UnityWebRequest.kHttpVerbGET);if (typeof(T) == typeof(byte[]))req.downloadHandler = new DownloadHandlerBuffer();else if (typeof(T) == typeof(Texture))req.downloadHandler = new DownloadHandlerTexture();else if (typeof(T) == typeof(AssetBundle))req.downloadHandler = new DownloadHandlerAssetBundle(req.url, 0);else if (typeof(T) == typeof(object))req.downloadHandler = new DownloadHandlerFile(localPath);else if (typeof(T) == typeof(AudioClip))req = UnityWebRequestMultimedia.GetAudioClip(path, type);else //如果出現沒有的類型 就不用繼續執行{Debug.LogWarning("未知類型" + typeof(T));yield break;}yield return req.SendWebRequest();if(req.result ==UnityWebRequest.Result.Success ){if (typeof(T) == typeof(byte[]))action?.Invoke(req.downloadHandler.data as T);else if (typeof(T) == typeof(Texture))//action?.Invoke((req.downloadHandler as DownloadHandlerTexture).texture as T);action?.Invoke(DownloadHandlerTexture.GetContent(req) as T);else if (typeof(T) == typeof(AssetBundle))action?.Invoke((req.downloadHandler as DownloadHandlerAssetBundle).assetBundle as T);else if (typeof(T) == typeof(object))action?.Invoke(null);else if (typeof(T) == typeof(AudioClip))action?.Invoke(DownloadHandlerAudioClip.GetContent(req) as T);}else{Debug.LogWarning("獲取數據失敗" + req.result + req.error + req.responseCode);}}public void SendMsg<T>(BaseMsg msg,UnityAction<T>action)where T:BaseMsg {StartCoroutine(SendMsgAsync<T>(msg, action));}private IEnumerator SendMsgAsync<T>(BaseMsg msg,UnityAction <T>action)where T:BaseMsg {//消息發送WWWForm data = new WWWForm();//準備要發送的消息數據data.AddBinaryData("Msg", msg.Writing());WWW www = new WWW(HTTP_SERVER_PATH, data);//我們也可以直接傳遞 2進制字節數組 只要和后端制定好規則 怎么傳都是可以的//WWW www = new WWW(HTTP_SERVER_PATH, msg.Writing());//異步等待 發送結束 才會繼續執行后面的代碼yield return www;//發送完畢后 收到響應//認為后端發回來的內容也是一個繼承自BaseMsg類的字節數組對象if(www.error ==null){//先解析 ID和消息長度int index = 0;int msgID = BitConverter.ToInt32(www.bytes, index);index += 4;int msgLength = BitConverter.ToInt32(www.bytes, index);index += 4;//反序列化 BaseMsgBaseMsg baseMsg = null;switch (msgID){case 1001:baseMsg = new PlayerMsg();baseMsg.Reading(www.bytes, index);break;}if (baseMsg != null)action?.Invoke(baseMsg as T);elseDebug.LogError("發消息出現問題" + www.error);}}public void UpLoadFile(string fileName,string localName,UnityAction<UnityWebRequest .Result> action){StartCoroutine(UpLoadFileAsync(fileName, localName, action));}private IEnumerator UpLoadFileAsync(string fileName,string localName,UnityAction<UnityWebRequest .Result> action){List<IMultipartFormSection> dataList = new List<IMultipartFormSection>();dataList.Add(new MultipartFormDataSection(fileName, File.ReadAllBytes(localName)));UnityWebRequest req = UnityWebRequest.Post(HTTP_SERVER_PATH, dataList);yield return req.SendWebRequest();action?.Invoke(req.result);if (req.result != UnityWebRequest.Result.Success){print("上傳失敗" + req.error + req.responseCode + req.result);}}}