UnityWebRequest
作者:追风剑情 发布于:2019-12-12 16:43 分类:Unity3d
示例一:上传视频
/// <summary>
/// 上传视频
/// </summary>
/// <param name="url">上传视频地址</param>
/// <param name="bytes">视频文件内容</param>
/// <returns></returns>
IEnumerator UpLoadVideo(string url, byte[] bytes)
{
yield return null;
WWWForm form = new WWWForm();
form.AddField("id", 123);
form.AddBinaryData("file", bytes, "my_video.mp4", "video/mp4");
//byte[] bodyRaw = Encoding.UTF8.GetBytes(postDataString);//发送原始数据(即,数据不组织成表单)
//UnityWebRequest request = new UnityWebRequest(url, "POST");
UnityWebRequest request = UnityWebRequest.Post(url, form);
request.timeout = 5;
//https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest-useHttpContinue.html
//true: 包含Expect: 100-Continue请求头, http会提前返回,这会导至后面的isNetworkError=true, responseCode=100
//false: 确保http请求完毕后再返回
request.useHttpContinue = false;
request.chunkedTransfer = false; //false:不希望服务器分块返回数据
request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
//如果不指定post表单,需要这样上传原始数据
//request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
//request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
//加上yield return 直到请求完成程序才会继续往下执行
//yield return request.SendWebRequest();
//调用后会立即返回,程序继续往下执行
request.SendWebRequest();
while (!request.isDone)
{
Debug.Log("上传进度: " + request.uploadProgress);
yield return new WaitForSeconds(0.1f);
}
if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
{
Debug.LogErrorFormat("上传视频出错\n{0}", request.error);
yield break; //跳出协程
}
Debug.Log("上传视频成功!");
}
// Post原始数据(即,非表单)
public IEnumerator PostRaw(string url, string data, Action completedCallback = null, Action errorCallback = null)
{
yield return null;
byte[] postBytes = Encoding.UTF8.GetBytes(data);
DownloadHandler downloadHandler = new DownloadHandlerBuffer();
UploadHandler uploadHandler = new UploadHandlerRaw(postBytes);
UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
request.SetRequestHeader("Accept", "application/json");
//设置Accept-Charset会报InvalidOperationException异常
//InvalidOperationException: Cannot override system-specified headers
//request.SetRequestHeader("Accept-Charset", "utf-8");
//request.SetRequestHeader("Content-Length", postBytes.Length.ToString());
request.timeout = 30; //单位:秒
request.useHttpContinue = false;//false:直接上传post数据,不需要发送前征询服务器情况
request.chunkedTransfer = false;//false:不希望服务器分块返回数据
request.downloadHandler = downloadHandler;
//如果不指定post表单,需要这样上传原始数据
request.uploadHandler = uploadHandler;
//yield return request.SendWebRequest(); //同步请求(请求完成后才会继续往下执行)
request.SendWebRequest(); //异步请求
while (!request.isDone)
yield return new WaitForSeconds(0.1f);
if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
{
Debug.LogErrorFormat("Post Error\n{0}", request.error);
if (errorCallback != null)
errorCallback();
yield break;//跳出协程
}
Debug.Log("Post完成!");
Debug.LogFormat("result={0}", request.downloadHandler.text);
string json = request.downloadHandler.text;
if (completedCallback != null)
completedCallback(json);
}
示例二:上传器
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net.Mime;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
/// <summary>
/// 资源上传器 (multipart/form-data)
/// </summary>
public class AssetUpLoader : MonoBehaviour
{
public static AssetUpLoader Instance { get; private set; }
public bool dontDestroyOnLoad = true;
public bool isSingleInstance = true;
//上传队列
private Queue<AssetObject> m_UploadQueue = new Queue<AssetObject>();
private bool m_UpLoading = false;
private void Awake()
{
if (dontDestroyOnLoad)
DontDestroyOnLoad(gameObject);
if (isSingleInstance)
Instance = this;
}
private void Update()
{
if (m_UpLoading || m_UploadQueue.Count <= 0)
return;
AssetObject asset = m_UploadQueue.Dequeue();
StartCoroutine(CoroutineUpLoad(asset));
}
public void UpLoad(AssetObject asset)
{
if (asset == null || string.IsNullOrEmpty(asset.url))
return;
m_UploadQueue.Enqueue(asset);
}
// 上传本地资源
public void UpLoadLocal(AssetObject asset)
{
StartCoroutine(UpLoadLocalCoroutine(asset));
}
private IEnumerator UpLoadLocalCoroutine(AssetObject asset)
{
yield return null;
Texture2D texture = null;
using (WWW www = new WWW(asset.localPath))
{
while (!www.isDone)
yield return null;
if (!string.IsNullOrEmpty(www.error)) {
Debug.LogErrorFormat("load local asset error: {0}\n{1}", www.error, www.url);
yield break;
}
texture = www.texture;
}
if (texture != null)
{
asset.bytes = texture.EncodeToJPG();
m_UploadQueue.Enqueue(asset);
}
}
/// <summary>
/// 上传资源
/// </summary>
/// <param name="url">上传地址</param>
/// <param name="bytes">资源内容</param>
/// <returns></returns>
IEnumerator CoroutineUpLoad(AssetObject assetObject)
{
Debug.LogFormat("begin upload: {0}", assetObject.fileName);
m_UpLoading = true;
yield return null;
DownloadHandler downloadHandler = new DownloadHandlerBuffer();
UnityWebRequest request = assetObject.unityWebRequest;
request.downloadHandler = downloadHandler;
request.SendWebRequest();
while (!request.isDone)
{
Debug.Log("上传进度: " + request.uploadProgress);
assetObject.uploadProgress = request.uploadProgress;
if (assetObject.OnProgressCallback != null)
assetObject.OnProgressCallback(assetObject);
yield return new WaitForSeconds(0.1f);
}
if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
{
Debug.LogErrorFormat("上传资源出错\n{0}\n{1}", request.error, assetObject.url);
if (assetObject.OnErrorCallback != null)
assetObject.OnErrorCallback(assetObject);
assetObject.Dispose();
m_UpLoading = false;
yield break;
}
Debug.Log("上传资源完成!");
Debug.LogFormat("{0}", request.downloadHandler.text);
assetObject.result = request.downloadHandler.text;
if (assetObject.OnCompletedCallback != null)
assetObject.OnCompletedCallback(assetObject);
assetObject.Dispose();
m_UpLoading = false;
}
/// <summary>
/// 表单编码方式
/// Multipart格式文档
// https://www.cnblogs.com/greenerycn/archive/2010/05/15/csharp_http_post.html
// https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
/// </summary>
public class FormEnctype
{
//对于发送大量二进制数据或包含非ASCII字符的文本效率不高
public const string APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
//提交包含文件,非ASCII数据和二进制数据的表单
public const string MULTIPART_FORM_DATA = "multipart/form-data";
}
/// <summary>
/// 资源对象
/// </summary>
public class AssetObject
{
public string headerContentType = FormEnctype.APPLICATION_X_WWW_FORM_URLENCODED;
public string id = string.Empty; //用户ID
public string url = string.Empty;
public string localPath = string.Empty; //本地资源路径
public byte[] bytes = null;
//.jpg "image/jpeg"
//.mp4 "video/mp4"
public string mimeType = string.Empty;
public string fileName = string.Empty;
public float uploadProgress = 0.0f;
public string result = string.Empty; //服务器返回数据
public Action<AssetObject> OnCompletedCallback;
public Action<AssetObject> OnProgressCallback;
public Action<AssetObject> OnErrorCallback;
public string MimeType
{
get
{
if (string.IsNullOrWhiteSpace(mimeType) && !string.IsNullOrWhiteSpace(fileName))
{
if (fileName.EndsWith(".jpg"))
mimeType = "image/jpeg";
else if (fileName.EndsWith(".png"))
mimeType = "image/png";
else if (fileName.EndsWith(".mp4"))
mimeType = "video/mp4";
}
return mimeType;
}
}
public WWWForm wwwForm
{
get
{
WWWForm form = new WWWForm();
form.AddField("id", id);
form.AddBinaryData("file", bytes, fileName, MimeType);
return form;
}
}
public UnityWebRequest unityWebRequest
{
get
{
UnityWebRequest request = null;
switch (headerContentType)
{
case FormEnctype.APPLICATION_X_WWW_FORM_URLENCODED:
request = UnityWebRequest.Post(url, wwwForm);
request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
break;
case FormEnctype.MULTIPART_FORM_DATA:
//分界线
byte[] boundary = UnityWebRequest.GenerateBoundary();
//结束分界线
byte[] terminate = Encoding.UTF8.GetBytes(String.Concat("\r\n--", Encoding.UTF8.GetString(boundary), "--"));
//Content-Type
string contentType = String.Concat("multipart/form-data; boundary=", Encoding.UTF8.GetString(boundary));
//表单
List<IMultipartFormSection> form = new List<IMultipartFormSection>();
form.Add(new MultipartFormFileSection("file", bytes, Path.GetFileName(fileName), MimeType));
//序列化表单
byte[] formSections = UnityWebRequest.SerializeFormSections(form, boundary);
byte[] body = new byte[formSections.Length + terminate.Length];
Buffer.BlockCopy(formSections, 0, body, 0, formSections.Length);
Buffer.BlockCopy(terminate, 0, body, formSections.Length, terminate.Length);
request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(body);
request.uploadHandler.contentType = contentType;
break;
}
request.timeout = 30;
request.useHttpContinue = false;
request.chunkedTransfer = false;
return request;
}
}
public void Dispose()
{
bytes = null;
OnCompletedCallback = null;
OnProgressCallback = null;
OnErrorCallback = null;
}
}
}
Http请求
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
/// <summary>
/// 与Web端交互
/// </summary>
public class HttpWebRequest : MonoBehaviour
{
public static HttpWebRequest Instance { get; private set; }
private void Awake()
{
DontDestroyOnLoad(gameObject);
Instance = this;
}
// Delete请求
public void Delete(string url, Action<string> completedCallback = null, Action<string> errorCallback = null)
{
StartCoroutine(DeleteRequest(url, completedCallback, errorCallback));
}
public IEnumerator DeleteRequest(string url, Action<string> completedCallback = null, Action<string> errorCallback = null)
{
yield return null;
Debug.LogFormat("DELETE: {0}", url);
UnityWebRequest request = DeleteUnityWebRequest(url);
//yield return request.SendWebRequest(); //同步请求(请求完成后才会继续往下执行)
request.SendWebRequest(); //异步请求
while (!request.isDone)
yield return new WaitForSeconds(0.1f);
if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
{
Debug.LogErrorFormat("DELETE Error\n{0}", request.error);
if (errorCallback != null)
errorCallback(request.error);
yield break;//跳出协程
}
Debug.Log("DELETE 请求返回!");
Debug.LogFormat("result={0}", request.downloadHandler.text);
string json = request.downloadHandler.text;
if (completedCallback != null)
completedCallback(json);
}
// Get请求
public void Get(string url, Action<string> completedCallback = null, Action<string> errorCallback = null)
{
StartCoroutine(GetRequest(url, completedCallback, errorCallback));
}
public IEnumerator GetRequest(string url, Action<string> completedCallback = null, Action<string> errorCallback = null)
{
yield return null;
Debug.LogFormat("GET: {0}", url);
UnityWebRequest request = GetUnityWebRequest(url);
//yield return request.SendWebRequest(); //同步请求(请求完成后才会继续往下执行)
request.SendWebRequest(); //异步请求
while (!request.isDone)
yield return new WaitForSeconds(0.1f);
if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
{
Debug.LogErrorFormat("GET Error\n{0}", request.error);
if (errorCallback != null)
errorCallback(request.error);
yield break;//跳出协程
}
Debug.Log("GET 请求返回!");
Debug.LogFormat("result={0}", request.downloadHandler.text);
string json = request.downloadHandler.text;
if (completedCallback != null)
completedCallback(json);
}
// Post原始数据(即,非表单)
public void Post(string url, string data, Action<string> completedCallback = null, Action<string> errorCallback = null)
{
StartCoroutine(PostRaw(url, data, completedCallback, errorCallback));
}
// Post原始数据(即,非表单)
public IEnumerator PostRaw(string url, string data, Action<string> completedCallback = null, Action<string> errorCallback = null)
{
yield return null;
Debug.LogFormat("POST: {0}\n{1}", url, data);
byte[] postBytes = Encoding.UTF8.GetBytes(data);
UnityWebRequest request = PostUnityWebRequest(url, data);
//yield return request.SendWebRequest(); //同步请求(请求完成后才会继续往下执行)
request.SendWebRequest(); //异步请求
while (!request.isDone)
yield return new WaitForSeconds(0.1f);
if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
{
Debug.LogErrorFormat("POST Error\n{0}", request.error);
if (errorCallback != null)
errorCallback(request.error);
yield break;//跳出协程
}
Debug.Log("POST 请求返回!");
Debug.LogFormat("result={0}", request.downloadHandler.text);
string json = request.downloadHandler.text;
if (completedCallback != null)
completedCallback(json);
}
// GET UnityWebRequest
public UnityWebRequest GetUnityWebRequest(string url)
{
DownloadHandler downloadHandler = new DownloadHandlerBuffer();
UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Accept", "application/json");
request.timeout = 10;
request.useHttpContinue = false;
request.chunkedTransfer = false;
request.downloadHandler = downloadHandler;
return request;
}
// POST UnityWebRequest
public UnityWebRequest PostUnityWebRequest(string url, string postData)
{
byte[] postBytes = Encoding.UTF8.GetBytes(postData);
DownloadHandler downloadHandler = new DownloadHandlerBuffer();
UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Accept", "application/json");
request.timeout = 10;
request.useHttpContinue = false;
request.chunkedTransfer = false;
request.downloadHandler = downloadHandler;
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
return request;
}
// DELETE UnityWebRequest
public UnityWebRequest DeleteUnityWebRequest(string url)
{
DownloadHandler downloadHandler = new DownloadHandlerBuffer();
UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbDELETE);
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Accept", "application/json");
request.timeout = 10;
request.useHttpContinue = false;
request.chunkedTransfer = false;
request.downloadHandler = downloadHandler;
return request;
}
}
UnityWebRequest request = new UnityWebRequest();
// Https 需要设置证书验证
request.certificateHandler = new AcceptAllCertificatesSignedWithASpecificKeyPublicKey();
using UnityEngine;
using UnityEngine.Networking;
using System.Security.Cryptography.X509Certificates;
/// <summary>
/// https://docs.unity3d.com/ScriptReference/Networking.CertificateHandler.ValidateCertificate.html
/// https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#.Net
/// </summary>
public class AcceptAllCertificatesSignedWithASpecificKeyPublicKey : CertificateHandler
{
// Encoded RSAPublicKey
private static string PUB_KEY = "3082010A0282010100C3D57BDD8594A0E4948CF35B24B2A5CC3D7455E8DADAF9C410EE6CCD7DDD0CEB4A9A62D4E065AED004E0467107A93CAF69A7CAB61A57A306171213F39C3E601D621B144D8C97674A9753177713C3A9571D1821D8EAAF821E21F94F88658E2CB68EC7994B5130CD24C89813BDD19F7DDA331900D5C70310F65FC5624BC65EF6327F1EF74896B18A59FD34F095762F9B376D5F74D187ECA86D807CACF37A597E89B2A0E690C4146971FBEA641E61AFA28C0F58A453092DEA570BA405C720A77621711BCE1A902CEC13BCC34FAEFBD67E7C671F3A85883D2F6D583843F000B1FCCAA068C09FA5DEF69F800002D332A60549C7216B3FF929B2B562EF0E3E97B776E90203010001";
//负责拒绝或接受在 https 请求上接收到的证书
//注意:自定义证书验证目前仅针对以下平台实施 - Android、iOS、tvOS 和桌面平台
//如果不需要验证,可以让这个方法直接返回true
protected override bool ValidateCertificate(byte[] certificateData)
{
X509Certificate2 certificate = new X509Certificate2(certificateData);
string pk = certificate.GetPublicKeyString();
if (pk.Equals(PUB_KEY))
return true;
// Bad dog
return false;
}
}
示例:Post发送表单
private IEnumerator PostFormCoroutine(string url, WWWForm form)
UnityWebRequest request = UnityWebRequest.Post(url, form);
request.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.timeout = 5;
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.ProtocolError ||
request.result == UnityWebRequest.Result.ConnectionError ||
request.result == UnityWebRequest.Result.DataProcessingError ||
request.responseCode != 200)
{
Debug.LogErrorFormat("Http请求出错({0})\n{1}", request.responseCode, request.error);
yield break; //跳出协程
}
string text = request.downloadHandler.text;
Debug.Log(text);
}
示例:Post发送json
private IEnumerator PostJsonCoroutine(string url, string json, string token)
UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
byte[] data = Encoding.UTF8.GetBytes(json);
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(data);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
//认证信息根据项目实际情况传参,这里仅作示范
request.SetRequestHeader("Authorization", token);
request.timeout = 5;
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.ProtocolError ||
request.result == UnityWebRequest.Result.ConnectionError ||
request.result == UnityWebRequest.Result.DataProcessingError ||
request.responseCode != 200)
{
Debug.LogErrorFormat("Http请求出错({0})\n{1}", request.responseCode, request.error);
yield break; //跳出协程
}
string text = request.downloadHandler.text;
Debug.Log(text);
}
注意,UnityWebRequest.Post()方法有bug,会使传到后台的json数据多个无效字符,导致json解析报错。
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Networking;
/// <summary>
/// Web请求辅助类
/// Unity 2022+ 默认不支持Http请求,需要在 Project Settings 中开启
/// [Project Settings -> Player -> Allow downloads over HTTP* 设置为 Always allowed]
/// </summary>
public sealed class WebRequestHelper
{
// 设置请求头
private static void SetRequestHeader(UnityWebRequest request, Dictionary<string, string> header = null)
{
if (request == null)
return;
request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
request.SetRequestHeader("Accept", "application/json");
request.SetRequestHeader("Authorization", "");
if (header == null)
return;
foreach (string key in header.Keys)
{
string value = header[key];
if (value == null)
continue;
request.SetRequestHeader(key, value);
}
}
// 解析
private static void ParseAsync(UnityWebRequestAsyncOperation async, Action<string> completedCallback = null, Action<string> errorCallback = null)
{
string error = async.webRequest.error;
if (!string.IsNullOrEmpty(error))
{
async.webRequest.Dispose();
if (errorCallback == null)
Debug.LogErrorFormat("请求出错: {0}", error);
errorCallback?.Invoke(error);
}
else
{
string text = async.webRequest.downloadHandler.text;
async.webRequest.Dispose();
completedCallback?.Invoke(text);
}
}
// 采用GET,向后端请求数据
public static UnityWebRequestAsyncOperation Get(string url, Dictionary<string, string> header = null)
{
DownloadHandler downloadHandler = new DownloadHandlerBuffer();
UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
request.downloadHandler = downloadHandler;
SetRequestHeader(request, header);
request.timeout = 5;
request.chunkedTransfer = false;
UnityWebRequestAsyncOperation async = request.SendWebRequest();
return async;
}
public static IEnumerator GetAsync(string url, Dictionary<string, string> header = null, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
{
yield return null;
UnityWebRequestAsyncOperation async = Get(url, header);
while (!async.isDone)
{
progressCallback?.Invoke(async.progress);
yield return new WaitForNextFrameUnit();
}
ParseAsync(async, completedCallback, errorCallback);
}
// 采用POST,向后端发送原始数据
public static UnityWebRequestAsyncOperation Post(string url, byte[] rawData, Dictionary<string, string> header = null)
{
DownloadHandler downloadHandler = new DownloadHandlerBuffer();
UploadHandler uploadHandler = new UploadHandlerRaw(rawData);
UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
request.downloadHandler = downloadHandler;
request.uploadHandler = uploadHandler;
SetRequestHeader(request, header);
request.timeout = 5;
UnityWebRequestAsyncOperation async = request.SendWebRequest();
return async;
}
public static UnityWebRequestAsyncOperation Post(string url, string rawData, Dictionary<string, string> header = null)
{
byte[] postBytes = Encoding.UTF8.GetBytes(rawData);
return Post(url, postBytes, header);
}
public static IEnumerator PostAsync(string url, string rawData, Dictionary<string, string> header, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
{
yield return null;
UnityWebRequestAsyncOperation async = Post(url, rawData, header);
while (!async.isDone)
{
progressCallback?.Invoke(async.progress);
yield return new WaitForNextFrameUnit();
}
ParseAsync(async, completedCallback, errorCallback);
}
// 表单请求 POST
public static IEnumerator PostFormAsync(string url, WWWForm form, Dictionary<string, string> header, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
{
yield return null;
UnityWebRequest request = UnityWebRequest.Post(url, form);
SetRequestHeader(request, header);
UnityWebRequestAsyncOperation async = request.SendWebRequest();
while (!async.isDone)
{
progressCallback?.Invoke(async.progress);
yield return new WaitForNextFrameUnit();
}
ParseAsync(async, completedCallback, errorCallback);
}
//默认请求头
public static Dictionary<string, string> GetDefaultRequestHeader()
{
Dictionary<string, string> header = new Dictionary<string, string>();
header.Add("Content-Type", "application/json;charset=UTF-8");
header.Add("Access-Control-Allow-0rigin", "*");
header.Add("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
header.Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
return header;
}
// 异步加载文本
public static IEnumerator LoadTextAsync(string url, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
{
using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
{
webRequest.SendWebRequest();
while (!webRequest.isDone)
{
progressCallback?.Invoke(webRequest.downloadProgress);
yield return null;
}
if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
|| webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
{
Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
errorCallback?.Invoke(webRequest.error);
}
else
{
var text = webRequest.downloadHandler.text;
completedCallback?.Invoke(text);
}
}
}
// 异步加载图片
public static IEnumerator LoadTextureAsync(string url, Action<Texture2D> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
{
using (UnityWebRequest webRequest = UnityWebRequestTexture.GetTexture(url))
{
webRequest.SendWebRequest();
while (!webRequest.isDone)
{
progressCallback?.Invoke(webRequest.downloadProgress);
yield return null;
}
if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
|| webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
{
Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
errorCallback?.Invoke(webRequest.error);
}
else
{
var texture = DownloadHandlerTexture.GetContent(webRequest);
completedCallback?.Invoke(texture);
}
}
}
// 异步加载 AudioClip
public static IEnumerator LoadAudioAsync(string url, Action<AudioClip> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
{
string ext = Path.GetExtension(url).ToLower();
AudioType audioType = AudioType.WAV;
switch (ext)
{
case ".wav":
audioType = AudioType.WAV;
break;
case ".mp3":
audioType = AudioType.MPEG;
break;
}
using (UnityWebRequest webRequest = UnityWebRequestMultimedia.GetAudioClip(url, audioType))
{
((DownloadHandlerAudioClip)webRequest.downloadHandler).streamAudio = true;
webRequest.SendWebRequest();
while (!webRequest.isDone)
{
progressCallback?.Invoke(webRequest.downloadProgress);
yield return null;
}
if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
|| webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
{
Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
errorCallback?.Invoke(webRequest.error);
}
else
{
var audioClip = DownloadHandlerAudioClip.GetContent(webRequest);
completedCallback?.Invoke(audioClip);
}
}
}
// 异步加载 AssetBundle
public static IEnumerator LoadAssetBundleAsync(string url, Action<AssetBundle> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
{
using (UnityWebRequest webRequest = UnityWebRequestAssetBundle.GetAssetBundle(url))
{
((DownloadHandlerAssetBundle)webRequest.downloadHandler).autoLoadAssetBundle = false;
webRequest.SendWebRequest();
while (!webRequest.isDone)
{
progressCallback?.Invoke(webRequest.downloadProgress);
yield return null;
}
if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
|| webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
{
Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
errorCallback?.Invoke(webRequest.error);
}
else
{
var assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest);
completedCallback?.Invoke(assetBundle);
assetBundle.Unload(false);
}
}
}
// 异步加载场景 AssetBundle
public static IEnumerator LoadSceneAssetBundleAsync(string url, Action<AssetBundle> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null, bool autoLoadScene = true, LoadSceneMode mode = LoadSceneMode.Single)
{
using (UnityWebRequest webRequest = UnityWebRequestAssetBundle.GetAssetBundle(url))
{
((DownloadHandlerAssetBundle)webRequest.downloadHandler).autoLoadAssetBundle = false;
webRequest.SendWebRequest();
while (!webRequest.isDone)
{
progressCallback?.Invoke(webRequest.downloadProgress);
yield return null;
}
if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
|| webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
{
Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
errorCallback?.Invoke(webRequest.error);
}
else
{
//向外部逻辑返回进度100%
progressCallback?.Invoke(webRequest.downloadProgress);
var assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest);
completedCallback?.Invoke(assetBundle);
if (autoLoadScene)
{
string sceneName = Path.GetFileNameWithoutExtension(url);
SceneManager.LoadScene(sceneName, mode);
}
//释放场景镜像资源。
//注意:必须等场景成功激活后再调用Unload,否则会出现材质和shader丢失。
//assetBundle.Unload(false);
}
}
}
// 上传图片
public static IEnumerator UploadTexture(string url, string filename, Dictionary<string, string> formField, Texture2D tex, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
{
yield return null;
if (tex == null)
{
Debug.LogError("上传的 Texture=null");
yield break;
}
if (string.IsNullOrEmpty(filename))
{
Debug.LogError("上传的 filename=null");
yield break;
}
//如果在非主线程调用EncodeToJPG()会报以下错。
//UnityException: EncodeToJPG can only be called from the main thread.
byte[] bytes = tex.EncodeToJPG();
WWWForm form = new WWWForm();
form.headers["Content-Type"] = "image/jpeg";
form.AddBinaryData("file", bytes, $"{filename}");
//添加更多字段参数
if (formField != null)
{
foreach (var key in formField.Keys)
{
string value = formField[key];
if (!string.IsNullOrEmpty(value))
form.AddField(key, formField[key]);
}
}
UnityWebRequest request = UnityWebRequest.Post(url, form);
UnityWebRequestAsyncOperation async = request.SendWebRequest();
while (!async.isDone)
{
progressCallback?.Invoke(async.progress);
yield return new WaitForNextFrameUnit();
}
ParseAsync(async, completedCallback, errorCallback);
}
}
标签: Unity3d
« 内部链接的静态变量
|
示例:计算屏幕分辨率比例»
日历
最新文章
随机文章
热门文章
分类
存档
- 2025年11月(1)
- 2025年9月(3)
- 2025年7月(4)
- 2025年6月(5)
- 2025年5月(1)
- 2025年4月(5)
- 2025年3月(4)
- 2025年2月(3)
- 2025年1月(1)
- 2024年12月(5)
- 2024年11月(5)
- 2024年10月(5)
- 2024年9月(3)
- 2024年8月(3)
- 2024年7月(11)
- 2024年6月(3)
- 2024年5月(9)
- 2024年4月(10)
- 2024年3月(11)
- 2024年2月(24)
- 2024年1月(12)
- 2023年12月(3)
- 2023年11月(9)
- 2023年10月(7)
- 2023年9月(2)
- 2023年8月(7)
- 2023年7月(9)
- 2023年6月(6)
- 2023年5月(7)
- 2023年4月(11)
- 2023年3月(6)
- 2023年2月(11)
- 2023年1月(8)
- 2022年12月(2)
- 2022年11月(4)
- 2022年10月(10)
- 2022年9月(2)
- 2022年8月(13)
- 2022年7月(7)
- 2022年6月(11)
- 2022年5月(18)
- 2022年4月(29)
- 2022年3月(5)
- 2022年2月(6)
- 2022年1月(8)
- 2021年12月(5)
- 2021年11月(3)
- 2021年10月(4)
- 2021年9月(9)
- 2021年8月(14)
- 2021年7月(8)
- 2021年6月(5)
- 2021年5月(2)
- 2021年4月(3)
- 2021年3月(7)
- 2021年2月(2)
- 2021年1月(8)
- 2020年12月(7)
- 2020年11月(2)
- 2020年10月(6)
- 2020年9月(9)
- 2020年8月(10)
- 2020年7月(9)
- 2020年6月(18)
- 2020年5月(4)
- 2020年4月(25)
- 2020年3月(38)
- 2020年1月(21)
- 2019年12月(13)
- 2019年11月(29)
- 2019年10月(44)
- 2019年9月(17)
- 2019年8月(18)
- 2019年7月(25)
- 2019年6月(25)
- 2019年5月(17)
- 2019年4月(10)
- 2019年3月(36)
- 2019年2月(35)
- 2019年1月(28)
- 2018年12月(30)
- 2018年11月(22)
- 2018年10月(4)
- 2018年9月(7)
- 2018年8月(13)
- 2018年7月(13)
- 2018年6月(6)
- 2018年5月(5)
- 2018年4月(13)
- 2018年3月(5)
- 2018年2月(3)
- 2018年1月(8)
- 2017年12月(35)
- 2017年11月(17)
- 2017年10月(16)
- 2017年9月(17)
- 2017年8月(20)
- 2017年7月(34)
- 2017年6月(17)
- 2017年5月(15)
- 2017年4月(32)
- 2017年3月(8)
- 2017年2月(2)
- 2017年1月(5)
- 2016年12月(14)
- 2016年11月(26)
- 2016年10月(12)
- 2016年9月(25)
- 2016年8月(32)
- 2016年7月(14)
- 2016年6月(21)
- 2016年5月(17)
- 2016年4月(13)
- 2016年3月(8)
- 2016年2月(8)
- 2016年1月(18)
- 2015年12月(13)
- 2015年11月(15)
- 2015年10月(12)
- 2015年9月(18)
- 2015年8月(21)
- 2015年7月(35)
- 2015年6月(13)
- 2015年5月(9)
- 2015年4月(4)
- 2015年3月(5)
- 2015年2月(4)
- 2015年1月(13)
- 2014年12月(7)
- 2014年11月(5)
- 2014年10月(4)
- 2014年9月(8)
- 2014年8月(16)
- 2014年7月(26)
- 2014年6月(22)
- 2014年5月(28)
- 2014年4月(15)
友情链接
- Unity官网
- Unity圣典
- Unity在线手册
- Unity中文手册(圣典)
- Unity官方中文论坛
- Unity游戏蛮牛用户文档
- Unity下载存档
- Unity引擎源码下载
- Unity服务
- Unity Ads
- wiki.unity3d
- Visual Studio Code官网
- SenseAR开发文档
- MSDN
- C# 参考
- C# 编程指南
- .NET Framework类库
- .NET 文档
- .NET 开发
- WPF官方文档
- uLua
- xLua
- SharpZipLib
- Protobuf-net
- Protobuf.js
- OpenSSL
- OPEN CASCADE
- JSON
- MessagePack
- C在线工具
- 游戏蛮牛
- GreenVPN
- 聚合数据
- 热云
- 融云
- 腾讯云
- 腾讯开放平台
- 腾讯游戏服务
- 腾讯游戏开发者平台
- 腾讯课堂
- 微信开放平台
- 腾讯实时音视频
- 腾讯即时通信IM
- 微信公众平台技术文档
- 白鹭引擎官网
- 白鹭引擎开放平台
- 白鹭引擎开发文档
- FairyGUI编辑器
- PureMVC-TypeScript
- 讯飞开放平台
- 亲加通讯云
- Cygwin
- Mono开发者联盟
- Scut游戏服务器引擎
- KBEngine游戏服务器引擎
- Photon游戏服务器引擎
- 码云
- SharpSvn
- 腾讯bugly
- 4399原创平台
- 开源中国
- Firebase
- Firebase-Admob-Unity
- google-services-unity
- Firebase SDK for Unity
- Google-Firebase-SDK
- AppsFlyer SDK
- android-repository
- CQASO
- Facebook开发者平台
- gradle下载
- GradleBuildTool下载
- Android Developers
- Google中国开发者
- AndroidDevTools
- Android社区
- Android开发工具
- Google Play Games Services
- Google商店
- Google APIs for Android
- 金钱豹VPN
- TouchSense SDK
- MakeHuman
- Online RSA Key Converter
- Windows UWP应用
- Visual Studio For Unity
- Open CASCADE Technology
- 慕课网
- 阿里云服务器ECS
- 在线免费文字转语音系统
- AI Studio
- 网云穿
- 百度网盘开放平台
- 迅捷画图
- 菜鸟工具
- [CSDN] 程序员研修院
- 华为人脸识别
- 百度AR导航导览SDK
- 海康威视官网
- 海康开放平台
- 海康SDK下载
- git download
- Open CASCADE
- CascadeStudio
交流QQ群
-
Flash游戏设计: 86184192
Unity游戏设计: 171855449
游戏设计订阅号






