文章目錄
- 1 UnityWebRequest 介紹
- 2 搭建 HTTP 服務器
- 3 常用操作
- 3.1下載資源
- 3.1.1 下載文本
- 3.1.2 下載圖片
- 3.1.3 下載 AB 包
- 3.2 上傳資源
- 3.2.1 上傳數據類
- 3.2.2 POST 上傳
- 3.3.3 PUT 上傳
- 4 自定義操作
- 4.1 下載資源
- 4.1.1 Unity 內置 Handler
- 4.1.2 自定義 Handler
- 4.2 上傳資源
- 4.2.1 UploadHandlerRaw
- 4.2.2 UploadHandlerFile
本文環境
- Windows 11
- Unity 6000.0.42f1
1 UnityWebRequest 介紹
? UnityWebRequest 是 Unity 提供的模塊化的系統類,用于構成 HTTP 請求和處理 HTTP 響應。
? 它主要目標是讓 Unity 游戲和 Web 服務端進行交互,將之前 WWW 的相關功能都集成在了其中,新版本中都建議使用 UnityWebRequest 類代替 WWW 類。
? UnityWebRequest 在使用上和 WWW 很類似,主要區別是 UnityWebRequest 把下載下來的數據處理單獨提取出來,可以根據自己的需求選擇對應的數據處理對象來獲取數據。
注意
- UnityWebRequest 和 WWW 一樣,需要配合協同程序使用。
- UnityWebRequest 和 WWW 一樣,支持 http、ftp、file 協議下載或加載資源。
- UnityWebRequest 能夠上傳文件到 HTTP 資源服務器。
常用操作
- 使用 Get 請求獲取文本或二進制數據。
- 使用 Get 請求獲取紋理數據。
- 使用 Get 請求獲取 AB 包數據。
- 使用 Post 請求發送數據。
- 使用 Put 請求上傳數據。
2 搭建 HTTP 服務器
- 搭建 HTTP 服務器過程參考:2025-05-11 Unity 網絡基礎10——HTTP通信-CSDN博客。
? Unity 默認不允許不安全的連接(如 HTTP),如果服務器是本地開發服務器,可以啟用 Unity 的 Allow downloads over HTTP
選項(位于 Edit > Project Settings > Player > Other Settings
)。

3 常用操作
3.1下載資源
3.1.1 下載文本
-
獲取文本或二進制數據時
使用
UnityWebRequest.Get()
。
using UnityEngine;namespace Lesson
{using System.Collections;using UnityEngine.Networking;public class Lesson30 : MonoBehaviour{// 在Start方法中啟動LoadText協程private void Start(){StartCoroutine(LoadText());}// 定義LoadText協程IEnumerator LoadText(){// 發送GET請求var req = UnityWebRequest.Get("http://你的 IP 地址:8000/HTTP Server/test.txt");// 等待請求完成yield return req.SendWebRequest();// 如果請求成功if (req.result == UnityWebRequest.Result.Success){// 打印下載的文本print(req.downloadHandler.text);// 獲取下載的字節數組var bytes = req.downloadHandler.data;// 打印字節數組的長度print("字節數組長度: " + bytes.Length);}// 如果請求失敗else{// 打印錯誤信息print($"獲取失敗: {req.error} | {req.result} | {req.responseCode}");}}}
}
? 將腳本掛載到 Unity 場景上并運行,得到以下結果。

3.1.2 下載圖片
-
獲取紋理圖片數據時
使用
UnityWebRequestTexture.GetTexture()
,以及
DownloadHandlerTexture.GetContent()
。該方法也支持
- ftp 下載。
- file 本地文件下載。
using UnityEngine;namespace Lesson
{using System.Collections;using UnityEngine.Networking;using UnityEngine.UI;public class Lesson30 : MonoBehaviour{// 聲明一個RawImage類型的變量Imgpublic RawImage Img;// 在Start方法中啟動LoadText協程private void Start(){StartCoroutine(LoadTexture());}IEnumerator LoadTexture(){// 創建一個UnityWebRequestTexture對象,用于獲取指定URL的紋理var req = UnityWebRequestTexture.GetTexture("http://你的 IP 地址:8000/HTTP Server/test.png");// var req = UnityWebRequestTexture.GetTexture("ftp://你的 IP 地址:8000/HTTP Server/test.png");// var req = UnityWebRequestTexture.GetTexture("file://" + Application.streamingAssetsPath + "/test.png");// 發送網絡請求yield return req.SendWebRequest();// 如果請求成功if (req.result == UnityWebRequest.Result.Success){// 方法一// Img.texture = (req.downloadHandler as DownloadHandlerTexture).texture;// 方法二// 獲取下載的紋理Img.texture = DownloadHandlerTexture.GetContent(req);}else{// 打印錯誤信息print($"獲取失敗: {req.error} | {req.result} | {req.responseCode}");}}}
}
? 將腳本掛載到 Unity 場景上,并在 Unity 場景中創建一個 RawImage 關聯至 Img。
? 運行 Unity,RawImage 上出現了從服務器下載的圖片。

3.1.3 下載 AB 包
-
獲取 AB 包數據時
使用
UnityWebRequestAssetBundle.GetAssetBundle()
,以及
DownloadHandlerAssetBundle.GetContent()
。
using UnityEngine;namespace Lesson
{using System.Collections;using UnityEngine.Networking;using UnityEngine.UI;public class Lesson30 : MonoBehaviour{// 在Start方法中啟動LoadText協程private void Start(){StartCoroutine(LoadAB());}IEnumerator LoadAB(){// 創建一個UnityWebRequest對象,用于獲取AssetBundleUnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle("http://你的 IP 地址:8000/HTTP Server/ab2");// 發送請求req.SendWebRequest();// 循環等待請求完成while (!req.isDone){// 打印下載進度print(req.downloadProgress);// 打印已下載的字節數print(req.downloadedBytes);// 等待一幀yield return null;}//yield return req.SendWebRequest();// 打印下載進度print(req.downloadProgress);// 打印已下載的字節數print(req.downloadedBytes);// 如果請求成功if (req.result == UnityWebRequest.Result.Success){// 獲取AssetBundle對象// AssetBundle ab = (req.downloadHandler as DownloadHandlerAssetBundle).assetBundle;// 獲取AssetBundle對象var ab = DownloadHandlerAssetBundle.GetContent(req);// 打印AssetBundle的名稱print(ab.name);}else{// 打印錯誤信息print($"獲取失敗: {req.error} | {req.result} | {req.responseCode}");}}}
}
3.2 上傳資源
3.2.1 上傳數據類
父接口:IMultipartFormSection
- 所有上傳數據類的父接口
- 可以使用父類容器存儲子類對象
var dataList = new List<IMultipartFormSection>();
子類1:MultipartFormDataSection
- 用于上傳普通數據
// 1. 二進制字節數組
dataList.Add(new MultipartFormDataSection(Encoding.UTF8.GetBytes("123123123123123")));// 2. 字符串
dataList.Add(new MultipartFormDataSection("12312312312312312dsfasdf"));// 3. 帶參數名和編碼類型(常用)
dataList.Add(new MultipartFormDataSection("Name", "xxx", Encoding.UTF8, "application/...."));// 4. 帶參數名的字節數組
dataList.Add(new MultipartFormDataSection("Msg", new byte[1024], "appl....."));
子類2:MultipartFormFileSection
- 用于上傳文件數據
// 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("12312313212312", "test.txt"));// 4. 帶編碼格式的字符串數據+文件名(常用)
dataList.Add(new MultipartFormFileSection("12312313212312", Encoding.UTF8, "test.txt"));// 5. 完整參數:表單名+字節數組+文件名+文件類型
dataList.Add(new MultipartFormFileSection("file", new byte[1024], "test.txt", ""));// 6. 完整參數:表單名+字符串數據+編碼格式+文件名
dataList.Add(new MultipartFormFileSection("file", "123123123", Encoding.UTF8, "test.txt"));
3.2.2 POST 上傳
基本流程
- 準備上傳數據列表。
- 創建
UnityWebRequest.POST
請求。 - 發送請求并監控進度。
- 處理響應結果。
using UnityEngine;namespace Lesson
{using System;using System.Collections;using System.Collections.Generic;using System.IO;using UnityEngine.Networking;using UnityEngine.UI;public class Lesson31 : MonoBehaviour{// 在Start方法中啟動LoadText協程private void Start(){StartCoroutine(Upload());}IEnumerator Upload(){// 創建一個包含要上傳的數據的列表var data = new List<IMultipartFormSection>{// 添加一個名為Name的表單字段,值為xxxnew MultipartFormDataSection("Name", "xxx"),// 添加一個名為png的文件字段,值為test.png文件的內容new MultipartFormFileSection("png", File.ReadAllBytes(Application.streamingAssetsPath + "/test.png")),// 添加一個名為txt的文本字段,值為12312321231232123new MultipartFormFileSection("txt", "12312321231232123"),};// 創建一個POST請求,將數據發送到指定的URLvar req = UnityWebRequest.Post("http://你的 IP 地址:8000/HTTP Server/", data);// 發送請求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}else{// 打印獲取失敗的信息print($"獲取失敗: {req.error} | {req.result} | {req.responseCode}");}}}
}
? 將腳本掛載到 Unity 場景上并運行,得到以下結果。

? 在服務器文件夾中,可看到上傳了 2 個文件(注意要確認可以匿名訪問服務器,才可上傳成功)。

3.3.3 PUT 上傳
- 不是所有服務器都支持 PUT 方法。
- 需要服務器端明確支持 PUT 請求處理。
IEnumerator UploadPut()
{var req = UnityWebRequest.Put("http://你的 IP 地址:8000/HTTP Server/", File.ReadAllBytes(Application.streamingAssetsPath + "/test.png"));yield return req.SendWebRequest();if (req.result == UnityWebRequest.Result.Success){print("Put 上傳成功");}else{ }
}
4 自定義操作
? 自定義作指使用 UnityWebRequest 提供的底層功能來處理常規封裝方法無法滿足的需求,核心思想是將數據處理與網絡傳輸分離。通過自定義 DownloadHandler 和 UploadHandler,實現更靈活的數據獲取和上傳功能。
相關 API
// 1.構造函數
UnityWebRequest req = new UnityWebRequest();// 2.請求地址
req.url = "服務器地址";// 3.請求類型
req.method = UnityWebRequest.kHttpVerbPOST;// 4.進度
req.downloadProgress
req.uploadProgress// 5.超時設置
req.timeout = 2000;// 6.上傳、下載的字節數
req.downloadedBytes
req.uploadedBytes// 7.重定向次數 設置為0表示不進行重定向 可以設置次數
req.redirectLimit = 10;// 8.狀態碼、結果、錯誤內容
req.result
req.error
req.responseCode// 9.下載、上傳處理對象
req.downloadHandler
req.uploadHandler
4.1 下載資源
4.1.1 Unity 內置 Handler
處理器類型 | 用途 | 示例 | 獲取數據方式 | 特點 |
---|---|---|---|---|
DownloadHandlerBuffer | 原始二進制數據 | new DownloadHandlerBuffer() | handler.data | 最基礎的處理方式 |
DownloadHandlerFile | 直接保存到文件 | new DownloadHandlerFile(path) | 自動保存到指定路徑 | 內存占用少,適合大文件 |
DownloadHandlerTexture | 圖片下載 | new DownloadHandlerTexture() | handler.texture | 自動轉換為 Texture2D |
DownloadHandlerAssetBundle | AB 包下載 | new DownloadHandlerAssetBundle(url, crc) | handler.assetBundle | 支持 CRC 校驗 |
DownloadHandlerAudioClip | 音頻下載 | UnityWebRequestMultimedia.GetAudioClip() | DownloadHandlerAudioClip.GetContent(req) | 需要指定音頻類型 |
? DownloadHandler 的使用基本遵循以下模式:
- 創建 UnityWebRequest 對象:指定 URL 和請求方法。
- 創建特定類型的 DownloadHandler:根據要下載的數據類型選擇。
- 將 DownloadHandler 賦給請求對象:
req.downloadHandler = handler
。 - 發送請求:
yield return req.SendWebRequest()
。 - 處理結果:檢查
req.result
,成功后通過 handler 獲取數據。
DownLoadTexture 示例
IEnumerator DownLoadTexture()
{// 創建一個UnityWebRequest對象,用于發送HTTP請求var req = new UnityWebRequest("http://你的 IP 地址:8000/Http Server/test.png",UnityWebRequest.kHttpVerbGET);// 創建一個DownloadHandlerTexture對象,用于處理下載的紋理var textureHandler = new DownloadHandlerTexture();// 將DownloadHandlerTexture對象賦值給UnityWebRequest對象的downloadHandler屬性req.downloadHandler = textureHandler;// 發送HTTP請求yield return req.SendWebRequest();// 如果請求成功if (req.result == UnityWebRequest.Result.Success){// 將下載的紋理賦值給Image對象的texture屬性Image.texture = textureHandler.texture;}else{// 打印錯誤信息print("獲取數據失敗" + req.result + req.error + req.responseCode);}
}
DownLoadAB 示例
IEnumerator DownLoadAB()
{// 創建一個UnityWebRequest對象,用于發送HTTP請求var req = new UnityWebRequest("http://你的 IP 地址:8000/Http Server/ab", UnityWebRequest.kHttpVerbGET);// 創建一個DownloadHandlerAssetBundle對象,用于處理下載的AssetBundle// 第二個參數需要已知校檢碼才能進行比較,檢查完整性。如果不知道的話只能傳0,不進行完整性的檢查// 所以一般只有進行AB包熱更新時,服務器發送對應的文件列表中包含了驗證碼才能進行檢查var handler = new DownloadHandlerAssetBundle(req.url, 0);// 將DownloadHandlerAssetBundle對象賦值給UnityWebRequest對象的downloadHandler屬性req.downloadHandler = handler;// 發送HTTP請求yield return req.SendWebRequest();// 如果請求成功if (req.result == UnityWebRequest.Result.Success){// 獲取下載的AssetBundlevar ab = handler.assetBundle;// 打印AssetBundle的名稱print(ab.name);}// 如果請求失敗else{// 打印錯誤信息print("獲取數據失敗" + req.result + req.error + req.responseCode);}
}
DownLoadAudioClip 示例
IEnumerator DownLoadAudioClip()
{// 創建一個UnityWebRequestMultimedia對象,用于獲取音頻文件var req = UnityWebRequestMultimedia.GetAudioClip("http://你的 IP 地址:8000/Http Server/Night Changes.mp3", AudioType.MPEG);// 發送網絡請求yield return req.SendWebRequest();// 如果請求成功if (req.result == UnityWebRequest.Result.Success){// 獲取音頻文件內容var a = DownloadHandlerAudioClip.GetContent(req);}// 如果請求失敗else{// 打印錯誤信息print("獲取數據失敗" + req.result + req.error + req.responseCode);}
}
? DownLoadAudioClip 中,由于創建時不是
new UnityWebRequest()
,而是指定了特殊的創建方法。因此不設置DownloadHandlerAudioClip
,而是通過DownloadHandlerAudioClip
獲得音頻文件。
4.1.2 自定義 Handler
? 以上這些類是 Unity 中實現的用于解析下載下來的數據的類,使用對應的類處理下載數據,他們就會在內部將下載的數據處理為對應的類型。
? DownloadHandlerScript
是一個特殊類,本身而言不會執行任何操作。但此類可由用戶定義的類繼承,接收來自 UnityWebRequest 系統的回調,然后使用這些回調在數據從網絡到達時執行完全自定義的數據處理。
自定義下載器
public class CustomDownLoadFileHandler : DownloadHandlerScript
{// 用于保存本地存儲時的路徑private string _savePath;// 用于緩存收到的數據的容器private byte[] _cacheBytes;// 這是當前已收到的數據長度private int _index = 0;public CustomDownLoadFileHandler() : base(){ }public CustomDownLoadFileHandler(byte[] bytes) : base(bytes){ }public CustomDownLoadFileHandler(string path) : base(){_savePath = path;}protected override byte[] GetData(){// 返回字節數組return _cacheBytes;}/// <summary>/// 從網絡收到數據后,每幀會自動調用的方法/// </summary>protected override bool ReceiveData(byte[] data, int dataLength){Debug.Log("收到數據長度:" + data.Length);Debug.Log("收到數據長度dataLength:" + dataLength);data.CopyTo(_cacheBytes, _index);_index += dataLength;return true;}/// <summary>/// 從服務器收到 Content-Length標頭時,會自動調用的方法/// </summary>protected override void ReceiveContentLengthHeader(ulong contentLength){// base.ReceiveContentLengthHeader(contentLength);Debug.Log("收到數據長度:" + contentLength);// 根據收到的標頭,決定字節數組容器的大小_cacheBytes = new byte[contentLength];}/// <summary>/// 當消息收完了會自動調用的方法/// </summary>protected override void CompleteContent(){Debug.Log("消息收完");// 把收到的字節數組進行自定義處理,我們在這處理成存儲到本地File.WriteAllBytes(_savePath, _cacheBytes);}
}
使用自定義下載器
using UnityEngine;namespace Lesson
{using System.Collections;using System.IO;using UnityEngine.Networking;using UnityEngine.UI;public class Lesson32 : MonoBehaviour{// 在Start方法中啟動LoadText協程private void Start(){StartCoroutine(DownLoadCustomHandler());}IEnumerator DownLoadCustomHandler(){// 創建一個UnityWebRequest對象,用于發送HTTP請求var req = new UnityWebRequest("http://你的 IP 地址:8000/Http Server/Night Changes.mp3", UnityWebRequest.kHttpVerbGET);// 使用自定義的下載處理對象來處理獲取到的2進制字節數組req.downloadHandler = new CustomDownLoadFileHandler(Application.streamingAssetsPath + "/Night Changes.mp3");// 發送HTTP請求yield return req.SendWebRequest();// 判斷請求是否成功if (req.result == UnityWebRequest.Result.Success){// 打印成功信息print("存儲本地成功");}else{// 打印失敗信息print("獲取數據失敗" + req.result + req.error + req.responseCode);}}public class CustomDownLoadFileHandler : DownloadHandlerScript{...}}
}
4.2 上傳資源
? UnityWebRequest 類的常用操作中,上傳數據相關內容已經封裝的很好了,可以很方便的上傳參數和文件,因此使用常用操作已經能夠滿足常用需求,以下內容主要做了解。
? UnityWebRequest 提供了兩種主要的上傳數據處理方式:
UploadHandlerRaw
- 用于上傳字節數組數據。UploadHandlerFile
- 用于上傳文件數據。
? 這些上傳處理器會自動處理數據轉換和傳輸過程,只需提供原始數據即可。
4.2.1 UploadHandlerRaw
- 功能:上傳原始字節數組數據。
- 特點
- 適合上傳結構化數據如 JSON、XML 等。
- 需要手動設置 contentType。
- 數據會被復制到 native 內存中。
IEnumerator UpLoadRaw()
{// 創建一個UnityWebRequest對象,指定請求的URL和請求方法var req = new UnityWebRequest("http://你的 IP 地址:8000/Http Server/", UnityWebRequest.kHttpVerbPOST);// 將字符串轉換為字節數組byte[] bytes = Encoding.UTF8.GetBytes("123123123123123");// 設置上傳處理程序,將字節數組作為上傳數據req.uploadHandler = new UploadHandlerRaw(bytes);// 設置上傳處理程序的Content-Type為application/octet-streamreq.uploadHandler.contentType = "application/octet-stream";// 發送請求,并等待響應yield return req.SendWebRequest();// 打印請求結果print(req.result);
}
4.2.2 UploadHandlerFile
- 功能:直接上傳文件內容。
- 特點:
- 適合上傳大文件,內存占用低。
- 文件會分塊讀取和上傳。
- 默認 contentType 為
application/octet-stream
。
IEnumerator UpLoadFile()
{// 創建一個UnityWebRequest對象,指定請求的URL和請求方法var req = new UnityWebRequest("http://你的 IP 地址:8000/Http Server/", UnityWebRequest.kHttpVerbPOST);// 設置上傳文件的路徑req.uploadHandler = new UploadHandlerFile(Application.streamingAssetsPath + "/test.png");// 發送請求并等待響應yield return req.SendWebRequest();// 打印請求結果print(req.result);
}
? UploadHandler 會自動處理 contentType,優先級如下:
- 如果在 UnityWebRequest 上手動設置了 Content-Type 頭,則使用該值。
- 如果在 UploadHandler 上設置了 contentType,則使用該值。
- 默認使用
application/octet-stream
。
常見 contentType 值
application/json
- JSON數據application/xml
- XML數據image/png
- PNG圖片application/octet-stream
- 二進制流(默認)
注意事項
UnityWebRequest 默認會在 Dispose 時自動釋放 uploadHandler。
如果需要保留 uploadHandler 引用,需設置
req.disposeUploadHandlerOnDispose = false;
使用 using 語句確保資源釋放。
using(UnityWebRequest req = new UnityWebRequest(...)) {// 使用請求 }