Introduction
UnityWebRequest is Unity's modern networking solution for handling HTTP communications. It provides a flexible system for sending requests to web servers and handling responses. This article covers the various HTTP methods and common usage scenarios.
Basic Usage
The fundamental approach involvse creating a UnityWebRequest instance and executing it within a coroutine. Here's a basic example:
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class NetworkManager : MonoBehaviour
{
void Start()
{
StartCoroutine(ExecuteRequest());
}
IEnumerator ExecuteRequest()
{
Uri targetUri = new Uri("https://www.example.com");
using (UnityWebRequest request = new UnityWebRequest(targetUri))
{
request.timeout = 10;
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.ConnectionError ||
request.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError($"Request failed: {request.error}");
}
else
{
Debug.Log("Request completed successfully");
}
}
}
}
GET Request
The GET method retrieves data from a specified URL. Unity provides a convenient helper method for this:
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class DataFetcher : MonoBehaviour
{
void Start()
{
StartCoroutine(FetchData());
}
IEnumerator FetchData()
{
UnityWebRequest request = UnityWebRequest.Get("https://api.example.com/data");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log($"Data retrieved. Size: {request.downloadedBytes} bytes");
string response = request.downloadHandler.text;
Debug.Log($"Response: {response}");
}
else
{
Debug.LogError($"Error: {request.error}");
}
}
}
POST Request
POST requests send form data to the server, commonly used for user authentication and data submission:
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class AuthService : MonoBehaviour
{
void Start()
{
StartCoroutine(Login("user@example.com", "password123"));
}
IEnumerator Login(string username, string password)
{
WWWForm formData = new WWWForm();
formData.AddField("username", username);
formData.AddField("password", password);
formData.AddField("remember", "true");
UnityWebRequest request = UnityWebRequest.Post("https://api.example.com/auth/login", formData);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log("Login successful");
string token = request.downloadHandler.text;
// Process token here
}
else
{
Debug.LogError($"Login failed: {request.error}");
}
}
}
PUT Request
PUT requests upload data to the server, useful for file uploads or data updates:
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class UploadManager : MonoBehaviour
{
void Start()
{
StartCoroutine(UploadData());
}
IEnumerator UploadData()
{
string payload = "Sample upload content";
byte[] bodyData = System.Text.Encoding.UTF8.GetBytes(payload);
using (UnityWebRequest request = UnityWebRequest.Put("https://api.example.com/upload", bodyData))
{
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log("Upload completed");
}
else
{
Debug.LogError($"Upload error: {request.error}");
}
}
}
}
HEAD Request
HEAD requests retrieve headers without downloading the full body. This is useful for checking file sizes or availability:
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class ResourceChecker : MonoBehaviour
{
void Start()
{
StartCoroutine(CheckResource());
}
IEnumerator CheckResource()
{
UnityWebRequest request = UnityWebRequest.Head("https://cdn.example.com/resource.zip");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log("Resource available");
// Retrieve content length from headers
string contentLength = request.GetResponseHeader("Content-Length");
if (!string.IsNullOrEmpty(contentLength))
{
long fileSize = long.Parse(contentLength);
Debug.Log($"File size: {fileSize} bytes");
}
string contentType = request.GetResponseHeader("Content-Type");
Debug.Log($"Content-Type: {contentType}");
}
else
{
Debug.LogError($"Check failed: {request.error}");
}
}
}
Download with Progress
For large files, implementing progress tracking provides better user feedback:
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class DownloadController : MonoBehaviour
{
public Slider progressSlider;
public Text percentageText;
private string downloadUrl = "https://example.com/large-file.zip";
private string savePath;
void Start()
{
savePath = Path.Combine(Application.persistentDataPath, "Downloads");
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
progressSlider.value = 0;
percentageText.text = "0%";
StartCoroutine(DownloadFile());
}
IEnumerator DownloadFile()
{
UnityWebRequest request = UnityWebRequest.Get(downloadUrl);
request.SendWebRequest();
while (!request.isDone)
{
progressSlider.value = request.downloadProgress;
percentageText.text = $"{Mathf.FloorToInt(request.downloadProgress * 100)}%";
yield return null;
}
if (request.result == UnityWebRequest.Result.Success)
{
progressSlider.value = 1.0f;
percentageText.text = "100%";
string fileName = Path.GetFileName(downloadUrl);
string fullPath = Path.Combine(savePath, fileName);
SaveToFile(fullPath, request.downloadHandler.data);
Debug.Log($"Download complete: {fullPath}");
}
else
{
Debug.LogError($"Download failed: {request.error}");
}
}
void SaveToFile(string path, byte[] data)
{
File.WriteAllBytes(path, data);
}
}
Important Notes
- Always use
UnityWebRequest.Resultinstead of checkingisNetworkErrorandisHttpErrorseparately for Unity 2020+ - Use the
usingstatement or manually dispose of requests to prevent memory leaks - Set appropriate timeout values for network operations
- Use
Application.persistentDataPathfor file storage on mobile devices - Always handle both network errors and HTTP error responses