如何在UnityWebRequest下载时实时获取请求数据而非等待完成?
Got it, your current coroutine waits for the entire HTTP request to finish before you can touch the response—but if you need to process data as it arrives (without waiting for the full response), you'll need to use Unity's streaming download handling instead of the default in-memory download. Here's a step-by-step solution:
1. Understand the Limitation of Your Current Code
Your existing code uses the default UnityWebRequest.Get(), which buffers the entire response into memory before triggering the completion of SendWebRequest(). To access data mid-download, we need to replace the default download handler with a custom one that processes chunks of data as they come in.
2. Create a Custom Streaming Download Handler
We'll make a subclass of DownloadHandlerScript—this lets us hook into the data-receive pipeline and handle each chunk in real time. We'll add a callback so we can pass the streaming data to other parts of your code:
using UnityEngine; using UnityEngine.Networking; using System; public class StreamingDownloadHandler : DownloadHandlerScript { // Callback to send streaming data to your other logic public Action<byte[], int> OnDataReceived; // Optional: Callback for when the download completes public Action OnDownloadComplete; public StreamingDownloadHandler() : base(new byte[4096]) // Use a 4KB buffer (adjust as needed) { } // This method is called EVERY TIME a chunk of data arrives protected override bool ReceiveData(byte[] data, int dataLength) { if (data == null || dataLength == 0) { Debug.LogWarning("Received empty data chunk"); return false; } // Pass the data chunk to your custom logic via the callback OnDataReceived?.Invoke(data, dataLength); return true; } // Called when the download finishes (success or failure) protected override void CompleteContent() { OnDownloadComplete?.Invoke(); Debug.Log("Streaming download completed"); } }
3. Modify Your Coroutine to Use the Streaming Handler
Now update your original coroutine to use this custom handler instead of the default one. We'll also wire up the callbacks to process the real-time data:
// Assume URL is your base API address defined elsewhere private string URL = "https://your-api-base-url.com"; public IEnumerator GetStreamingCoroutine(string route) { string finalURL = URL + route; UnityWebRequest www = new UnityWebRequest(finalURL, "GET"); // Attach our custom streaming handler var streamingHandler = new StreamingDownloadHandler(); // Wire up the real-time data callback streamingHandler.OnDataReceived += (data, length) => { // Process the data chunk here! // Example: Convert bytes to string (for text-based responses like JSON/XML) string chunkText = System.Text.Encoding.UTF8.GetString(data, 0, length); Debug.Log($"Received chunk: {chunkText}"); // Pass this chunk to other systems (e.g., parse partial JSON, update UI, etc.) // Important: This callback runs on a background thread! // If you need to call Unity API (like UI updates), use a main thread dispatcher pattern. }; // Wire up the completion callback (optional) streamingHandler.OnDownloadComplete += () => { Debug.Log("All data received"); }; www.downloadHandler = streamingHandler; // Send the request—this will trigger ReceiveData calls as data arrives yield return www.SendWebRequest(); // Handle errors as before if (www.isNetworkError || www.isHttpError) { Debug.LogError($"Request failed: {www.error}"); } // Clean up resources www.Dispose(); }
Key Notes to Remember
- Buffer Size: The
new byte[4096]in the handler constructor sets the chunk size—adjust this based on your needs (smaller chunks = more frequent callbacks, larger chunks = fewer but bigger updates). - Thread Safety: The
ReceiveDatamethod runs on a background thread, so you can't directly call Unity API (likeGameObject.SetActive()or UI updates) from it. If you need to update Unity objects, use a main thread dispatcher (e.g., a queue that you process inUpdate()). - Binary Data: If you're downloading binary files (images, audio), skip the UTF8 conversion and process the raw
byte[]directly in the callback. - Error Handling: Don't forget to keep the existing error checks—even with streaming, network/HTTP errors can still occur mid-download.
How to Use This
Just call your new coroutine instead of the old one:
StartCoroutine(GetStreamingCoroutine("/your-api-endpoint"));
内容的提问来源于stack exchange,提问作者Josean Muñoz

