El UnityWebRequest es un remplazo para el objeto WWW original de Unity. Este proporciona un sistema modular para componer peticiones HTTP y manejar respuestas HTTP. El objetivo principal del sistema de UnityWebRequest es permitirle a los juegos de Unity interactuar con backends Web modernos. También soporta características de alta demanda tal como solicitudes HTTP fragmentadas, operaciones de streaming POST/PUT y un control completo sobre encabezados HTTP y verbs.
Para usuarios finales que solamente emplean casos de uso WWW comunes, darle transición al nuevo sistema debería ser un proceso de encuentre-y-remplace.
El sistema consiste en dos capas. Una API de bajo nivel (LLAPI) proporciona una flexibilidad máxima para usuarios avanzados, mientras que hay una API de alto nivel (HLAPI) que envuelve la API de bajo nivel y proporciona una interfaz conveniente para realizar operaciones comunes.
El sistema de UnityWebRequest soporta la mayoría de plataformas de Unity, con la excepción notable del Unity Web Player.
Plataformas soportadas en 5.2:
Plataformas soportadas en 5.3:
Un soporte adicional de plataformas será implementado en lanzamientos adicionales 5.x:
El ecosistema de UnityWebRequest rompe una transacción HTTP a tres operaciones distintas:
Para proporcionar una mejor interfaz para usuarios avanzados, estas operaciones cada una están gobernadas por sus propios objetos:
UploadHandler
maneja la transmisión de datos al servidorDownloadHandler
maneja el recibimiento, buffering y post-procesamiento de datos recibidos del servidorUnityWebRequest object
, que maneja otros dos objetos, y también maneja el control del flujo HTTP. Este objeto es dónde encabezados personalizados y URLs son definidos, y dónde la información de error y re-dirección está almacenada.Para cualquier transacción HTTP dada, el flujo del código genérico es:
Send()
para esperar que la solicitud se complete, como WWW.Esta sección detalla las operaciones disponibles en la API de Alto Nivel, y los escenarios que intentan abarcar.
Para recuperar datos simple, como datos de texto o binarios, de un servidor estándar HTTP o de uno HTTPS web, el llamado para utilizar es UnityWebRequest.GET. Este método toma un solo string como un argumento; el string específica el URL del cual los datos serán recuperados.
Este método es análogo al constructor estándar WWW:
WWW myWww = new WWW("http://www.myserver.com/foo.txt");
// ... is analogous to ...
UnityWebRequest myWr = UnityWebRequest.Get("http://www.myserver.com/foo.txt");
Este método crea un UnityWebRequest
y configura la URL objetivo al argumento string. No configura otros flags personalizados o encabezados.
Por defecto, este método adjunta un DownloadHandlerBuffer
al UnityWebRequest
. Este manejador (handler) va a buffer los datos recibidos del servidor y lo hará disponible a sus scripts cuando la petición sea completada.
Por defecto, este método no adjunta un UploadHandler
al UnityWebRequest
. Usted puede adjuntar uno manualmente si desea.
Ejemplo:
using UnityEngine;
using System.Collections;
+using UnityEngine.Networking;
class MyBehaviour: public MonoBehaviour {
void Start() {
StartCoroutine(GetText());
}
IEnumerator GetText() {
UnityWebRequest www = UnityWebRequest.Get("http://www.my-server.com");
yield return www.Send();
if(www.isError) {
Debug.Log(www.error);
}
else {
// Show results as text
Debug.Log(www.downloadHandler.text);
// Or retrieve results as binary data
byte[] results = www.downloadHandler.data;
}
}
}
Para recuperar un archivo de textura de un servidor remoto, usted puede utilizar UnityWebRequest.Texture.
Este método es muy similar a UnityWebRequest.GET
, pero es optimizado para descargar y almacenar texturas eficientemente.
Este método toma un solo string como un argumento. El string específica el URL del cual usted quiere descargar un archivo de imagen para que sea usado como una textura.
Este método crea un UnityWebRequest
y configura el URL objetivo al argumento string. Este método no configura otras flags o encabezados personalizados.
Este método adjunta un objeto DownloadHandlerTexture
al UnityWebRequest
. DownloadHandlerTexture es u Download Handler (manejador de descargas) especializado el cual es optimizado para ser utilizado como texturas en el motor de Unity. Utilizar esta clase significativamente reduce la re-asignación de memoria comparado a descargar raw bytes y crear una textura manualmente desde script.
Por defecto, este método adjunta un Upload Handler (manejador de subidas). Usted pede agregar uno manualmente si desea.
Ejemplo:
using UnityEngine;
using System.Collections;
class MyBehaviour: public MonoBehaviour {
void Start() {
StartCoroutine(GetTexture());
}
IEnumerator GetTexture() {
UnityWebRequest www = UnityWebRequest.GetTexture("http://www.my-server.com/image.png");
yield return www.Send();
if(www.isError) {
Debug.Log(www.error);
}
else {
Texture myTexture = ((DownloadHandlerTexture)www.downloadHandler).texture;
}
}
}
Alternatively, you can implement GetTexture using a helper getter:
IEnumerator GetTexture() {
UnityWebRequest www = UnityWebRequest.GetTexture("http://www.my-server.com/image.png");
yield return www.Send();
Texture myTexture = DownloadHandlerTexture.GetContent(www);
}
Para recuperar un asset bundle de un servidor remoto, usted puede utilizar UnityWebRequest.AssetBundle. Este método streams datos a un buffer interno, que decodifica/descomprime los datos del asset bundle en un hilo worker.
Los argumentos de este método toman varias formas. En su forma más simple, toma solo la URL de dónde el asset bundle debe ser descargado. Usted podría opcionalmente proporcionar un checksum (suma de verificación) para verificar la integridad de los datos descargados.
Alternativamente, si usted desea utilizar el sistema de almacenamiento de caché del asset bundle, usted podría proporciona ya sea un número de versión o una estructura de datos Hash128. Estas son idénticas a los version numbers (números de versiones) o Hash128 objects
proporcionados a los sistemas viejos vía WWW.LoadFromCacheOrDownload
.
Este método crea un UnityWebRequest
y configura el URL objetivo al argumento URL proporcionado. También configura el verb HTTP a GET
, pero no configura otras flags o encabezados personalizados.
Este método adjunta un DownloadHandlerAssetBundle
al UnityWebRequest
. Este download handler (manejador de descargas) tiene una propiedad especial assetBundle
, que puede ser utilizada para extrar el asset bundle una vez suficientes datos hayan sido descargados y decodificados para permitir un acceso a los recursos dentro del bundle.
Si usted proporciona un número de versión o un objeto Hash128
como un argumento, también pasa esos argumentos al DownloadHandlerAssetBundle
. El download handler va luego a emplear el sistema de almacenamiento en caché.
Ejemplo:
using UnityEngine;
using System.Collections;
class MyBehaviour: public MonoBehaviour {
void Start() {
StartCoroutine(GetAssetBundle());
}
IEnumerator GetAssetBundle() {
UnityWebRequest www = UnityWebRequest.GetAssetBundle("http://www.my-server.com/myData.unity3d");
yield return www.Send();
if(www.isError) {
Debug.Log(www.error);
}
else {
AssetBundle bundle = ((DownloadHandlerAssetBundle)www.downloadHandler).assetBundle;
}
}
}
Alternativamente, usted puede implementar GetAssetBundle
utilizando un getter de ayuda:
IEnumerator GetTexture() {
UnityWebRequest www = UnityWebRequest.GetAssetBundle("http://www.my-server.com/myData.unity3d");
yield return www.Send();
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);
}
Hay dos métodos principales para enviar datos al servidor, formateado como un FORM HTML
Para ayudar migrar del sistema anterior WWW, el nuevo sistema UnityWebRequest le permite a usted utilizar el objeto anterior WWWForm para proporcionar datos de formulario.
En este caso, la function signature es:
WebRequest.Post(string url, WWWForm formData);
Este método crea un nuevo UnityWebRequest
y configura el URL objetivo al primer valor string del argumento. También lee cualquier encabezado personalizado generado por el argumento WWWForm
(tal como Content-Type) y los copia al UnityWebRequest
.
Este método, por defecto, adjunta un DownloadHandlerBuffer
al UnityWebRequest
. Este es por convenience: usted puede utilizar esto para revisar por las respuestas de su servidor.
Este método lee datos raw generados por el WWWForm object
y los buffer en un objeto UploadHandlerRaw
, que es adjuntado al UnityWebRequest
. Por lo tanto cambios al objeto WWWForm
después de llamar UnityWebRequest.POST
no va a alterar el contenido del UnityWebRequest
.
Ejemplo:
using UnityEngine;
using System.Collections;
class MyBehavior: public MonoBehaviour {
void Start() {
StartCoroutine(Upload());
}
IEnumerator Upload() {
WWWForm form = new WWWForm();
form.AddField("myField", "myData");
UnityWebRequest www = UnityWebRequest.Post("http://www.my-server.com/myform", form);
yield return www.Send();
if(www.isError) {
Debug.Log(www.error);
}
else {
Debug.Log("Form upload complete!");
}
}
}
Para proporcionar un mayor control sobre cómo especificar los datos de su form, el sistema de UnityWebRequest
contiene una interfaz (implementada por el usuario) IMultipartFormSection
. Para aplicaciones estándar, Unity también proporciona implementaciones por defecto para secciones de datos y archivos: MultipartFormDataSection
y MultipartFormFileSection
.
Una sobrecarga de UnityWebRequest.POST
acepta, como un segundo parámetro, una lista de argumentos, cuyos miembros deben todos ser IMultipartFormSections
. La function signature es:
WebRequest.Post(string url, List<IMultipartFormSection> formSections);
Este método crea un UnityWebRequest
y configura la URL objetivo al primer parámetro string. También configura el encabezado Content-type del UnityWebRequest
apropiadamente para los datos form especificados en la lista de objetos IMultipartFormSection
.
Este método, por defecto, adjunta un DownloadHandlerBuffer
al UnityWebRequest
. Este es por convenience: usted puede utilizar esto para revisar por las respuestas de su servidor.
Similar al método WWWForm POST
, este método HLAPI va a llamar cada IMultipartFormSection
proporcionado devuelta y los va a formatear a un form estándar multipart como se especifica en RFC 2616.
Los datos form pre-formateados serán almacenados en un objeto estándar UploadHandlerRaw
, que es luego adjuntado al UnityWebRequest
. Como resultado, cambios a los objetos `IMultipartFormSectionrealizados después de la llamada U
nityWebRequest.POST`` no serán reflejados en los datos enviados al servidor.
Ejemplo:
using UnityEngine;
using System.Collections;
class MyBehavior: public MonoBehaviour {
void Start() {
StartCoroutine(Upload());
}
IEnumerator Upload() {
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add( new MultipartFormDataSection("field1=foo&field2=bar") );
formData.Add( new MultipartFormFileSection("my file data", "myfile.txt") );
UnityWebRequest www = UnityWebRequest.Post("http://www.my-server.com/myform", formData);
yield return www.Send();
if(www.isError) {
Debug.Log(www.error);
}
else {
Debug.Log("Form upload complete!");
}
}
}
Algunas aplicaciones web modernas prefieren que los archivos sean subidos vía el verb HTTP put. Para este escenario, Unity proporciona el método UnityWebRequest.PUT.
Este método toma dos argumentos. El primer argumento es un string y específica el URL objetivo para la solicitud. El segundo argumento podría ser un string o un arreglo de byte, y específica el payload de datos en ser enviados al servidor.
Function signatures:
WebRequest.Put(string url, string data);
WebRequest.Put(string url, byte[] data);
Este método crea un UnityWebRequest
y configura el content type a application/octet-stream
.
Este método adjunta un DownloadHandlerBuffer
estándar al UnityWebRequest
. Como con los métodos POST, usted puede utilizar esto para devolver datos de resultado de sus aplicaciones.
Este método almacena los datos input de upload en un objeto UploadHandlerRaw
estándar y lo adjunta al UnityWebRequest
. Como resultado, si utiliza el método byte[], cualquier cambio al arreglo byte realizado después de la llamada UnityWebRequest.PUT
no será reflejado en los datos subidos al servidor.
Ejemplo:
using UnityEngine;
using System.Collections;
class MyBehavior: public MonoBehaviour {
void Start() {
StartCoroutine(Upload());
}
IEnumerator Upload() {
byte[] myData = System.Text.Encoding.UTF8.GetBytes("This is some test data");
UnityWebRequest www = UnityWebRequest.Put("http://www.my-server.com/upload", myData);
yield return www.Send();
if(www.isError) {
Debug.Log(www.error);
}
else {
Debug.Log("Upload complete!");
}
}
}
Mientras la HLAPI está diseñada para minimizar la repetición de código, la LLAPI está diseñada para permitir una mayor flexibilidad. En general, utilizar la LLAPI involucra crear UnityWebRequests, luego crear DownloadHandlers
apropiados o UploadHandlers
y luego adjuntarlos a su UnityWebRequests
.
Para detalles completos en cada uno de los objetos descritos en esta sección, por favor referirse a la Scripting Reference.
Tenga en cuenta: La HLAPI y la LLAPI no son mutuamente excluyentes. Usted puede siempre personalizar objetos UnityWebRequest creados vía la HLAPi si usted necesita afinar un escenario común.
Los WebRequests puede ser simplemente instanciados como cualquier otro objeto. Los dos constructors están disponibles. El estándar, constructor sin parámetros crea un nuevo UnityWebRequest con todos sus ajustes en blanco o por defecto: * El URL objetivo no está configurado * No hay encabezados personalizados configurados * El limite de re-dirección está configurado a 32
El segundo constructor toma un argumento string. Lo asigna a la URL objetivo del UnityWebRequest al valor del argumento string, y de lo contrario es identico al constructor sin parámetros.
UnityWebRequest wr = new UnityWebRequest(); // Completely blank
UnityWebRequest wr2 = new UnityWebRequest("http://www.mysite.com"); // Target URL is set
Actualmente, un solo tipo de upload handler es disponible: UploadHandlerRaw
. Esta clase acepta un data buffer en tiempo de construcción. Este buffer es copiado internamente a memoria de código nativo y luego utilizado por el sistema de UnityWebRequest
cuando el servidor remoto está listo para aceptar body data.
Los Upload Handlers también aceptan un string Content Type. Este string también sera utilizado por el valor de encabezado Content-type de UnityWebRequest si usted no configura un encabezado Content-type en el UnityWebRequest en sí. Si usted manualmente configura un encabezado Content-Type en el objeto UnityWebRequest, entonces el Content-Type en el objeto Upload Handler será ignorado.
Si usted no configura un Content-Type en cualquiera del UnityWebRequest o el UploadHandler
, entonces el sistema de forma predeterminada va a configurar un Content-type de application/octet-stream
.
Ejemplo:
byte[] payload = new byte[1024];
// ... fill payload with data ...
UnityWebRequest wr = new UnityWebRequest("http://www.mysite.com/data-upload");
UploadHandler uploader = new UploadHandlerRaw(payload);
// Will send header: "Content-Type: custom/content-type";
uploader.contentType = "custom/content-type";
wr.uploadHandler = uploader;
Actualmente hay cuatro tipos de DownloadHandlers
:
DownloadHandlerBuffer
almacena los datos recibidos en un buffer byte de código nativo, y permite acceso ya sea a raw bytes o va a convertirlo a un string UTF8.DownloadHandlerTexture
almacena datos recibidos en una UnityEngine.Texture
. Cuando se complete la descarga, va a decodificar JPEG y PNGs a UnityEngine.Texture objects
validos. Solamente una copie de UnityEngine.Texture
será creada por objeto DownloadHandlerTexture
, lo cual va a reducir hits de rendiento del garbage collection.DownloadHandlerAssetBundle
streams datos recibidos al sistema de asset bundle de Unity. Una vez el sistema de asset bundle ha recibido los suficientes datos, el asset bundle va a estar disponible como un objeto UnityEngine.AssetBundle
. Como arriba, solo una copia del objeto UnityEngine.AssetBundle
será creada para reducir el impacto de memoria.DownloadHandlerScript
es un caso especial. En sí, no hará nada. Sin embargo, esta clase puede ser heredada por una clase definida por el usuario. Esta clase va a recibir callbacks del sistema de UnityWebRequest, el cual puede ser luego utilizado para realizar un manejo personalizado de datos a medida que llegan de la red.Un Download Handler especializado para Audio Clips también está disponible. Los APIs son análogos a la interfaz DownloadHandlerTexture
.
Esta download handler es el más simple y maneja la mayoría de casos de uso. Simplemente almacena datos recibidos en un buffer (código-nativo). Cuando la descarga se haya completado, usted puede acceder los datos buffered ya sea en un arreglo de bytes o como un string UTF8.
Example:
using UnityEngine;
using System.Collections;
class MyBehaviour: public MonoBehaviour {
void Start() {
StartCoroutine(GetText());
}
IEnumerator GetText() {
UnityWebRequest www = new UnityWebRequest("http://www.my-server.com");
www.downloadHandler = new DownloadHandlerBuffer();
yield return www.Send();
if(www.isError) {
Debug.Log(www.error);
}
else {
// Show results as text
Debug.Log(www.downloadHandler.text);
// Or retrieve results as binary data
byte[] results = www.downloadHandler.data;
}
}
}
Mientras usted puede utilizar DownloadHandlerBuffer
para descargar un archivo de imagen, y luego crear una textura de bytes crudos utilizando Texture.LoadImage
, es más eficiente utilizar DownloadHandlerTexture
.
Este download handler realizar el buffering, des-compresión y creación de textura en código nativo. Adicionalmente, la des-compresión y creación de textura son realizadas en un hilo worker en vez del hilo principal, el cual puede mejorar el tiempo de frame cuando se cargue texturas grandes.
Finalmente DownloadHandlerTexture
solo asigna memoria manejada cuando finalmente se cree la textura en sí, lo cual elimina la sobrecarga del garbage collection asociado con realizar una conversión byte-to-textura en script.
El siguiente ejemplo descarga un PNG del internet, lo convierte a un Sprite y lo asigna a una imagen uGUI:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
[RequireComponent(typeof(UnityEngine.UI.Image))]
public class ImageDownloader : MonoBehaviour {
UnityEngine.UI.Image _img;
void Start () {
_img = GetComponent<UnityEngine.UI.Image>();
Download("http://www.mysite.com/myimage.png");
}
public void Download(string url) {
StartCoroutine(LoadFromWeb(url));
}
IEnumerator LoadFromWeb(string url)
{
UnityWebRequest wr = new UnityWebRequest(url);
DownloadHandlerTexture texDl = new DownloadHandlerTexture(true);
wr.downloadHandler = texDl;
yield return wr.Send();
if(!wr.isError) {
Texture2D t = texDl.texture;
Sprite s = Sprite.Create(t, new Rect(0, 0, t.width, t.height),
Vector2.zero, 1f);
_img.sprite = s;
}
}
}
La ventaja de este download handler especializado es que es capaz de streamear datos al sistema de asset bundle de Unity. Esto considerablemente reduce la asignación de memoria en tiempo de ejecución, al igual que el impacto de memoria de cargar sus asset bundles. Adicional, le permite a los asset bundles en ser parcialmente utilizados mientras no están completamente descargados - esto es, usted puede stream assets.
Toda la descarga y descompresión ocurre en hilos worker.
Los Asset Bundles son descargados vía un objeto DownloadHandlerAssetBundle
, que tiene una propiedad especial assetBundle
para recuperar el asset bundle.
Debido a la manera en el que el sistema de Asset Bundle funciona, todos los asset bundles deben tener una dirección asociada a ellos. Generalmente, esta es la URL nominal en la cual son ubicados (i.e. el URL anterior redirecciona). En la mayoría de casos, usted debería simplemente pasar la misma URL como paso el UnityWebRequest. Cuando utilice el HLAPI, esto hecho para usted.
Ejemplo:
using UnityEngine;
using System.Collections;
class MyBehaviour: public MonoBehaviour {
void Start() {
StartCoroutine(GetAssetBundle());
}
IEnumerator GetAssetBundle() {
UnityWebRequest www = new UnityWebRequest("http://www.my-server.com");
DownloadHandlerAssetBundle handler = new DownloadHandlerAssetBundle(www.url);
www.downloadHandler = handler;
yield return www.Send();
if(www.isError) {
Debug.Log(www.error);
}
else {
// Extracts asset bundle
AssetBundle bundle = handler.assetBundle;
}
}
}
Para usuarios avanzados que requieren un control completo sobre el procesamiento de datos descargados, Unity proporciona la clase DownloadHandlerScript
.
Por defecto, las instancias de esta clase harán nada. Sin embargo, si usted deriva sus propias clases de DownloadHandlerScript
, usted podría anular ciertos métodos y utilizarlos para recibir callbacks a medida que los datos llegan de la red.
Tenga en cuenta: Incluso si la descarga actual ocurre en un hilo worker, todos los callbacks DownloadHandlerScript
operan en el hilo principal. Evite realizar operaciones pesadas de computación durante estos callbacks.
protected void ReceiveContentLength(long contentLength);
Este método se llama cuando el encabezado del Content-Length es recibido.
Tenga en cuenta: Este callback puede ocurrir múltiples veces si su servidor emite una o más respuestas que redireccionan sobre el curso del procesamiento de su UnityWebRequest.
protected void OnContentComplete();
Este método es llamado cuando el UnityWebRequest ha descargado completamente todos los datos del servidor, y ha remitido todos los datos recibidos al callback ReceiveData.
protected bool ReceiveData(byte[] data, long dataLength);
Este método se llama después de que los datos han llegado del servidor remoto. Este método va a ser llamado una vez por frame. El método será llamado una vez por frame. El argumento de los datos contiene los bytes crudos recibido del servidor remoto, y el dataLength indica el tamaño de los nuevos datos en el arreglo de datos.
Cuando no esté utilizando buffers de datos pre-asignados, el sistema va a crear un nuevo arreglo byte cada vez que llame este callback, y dataLength va a ser siempre igual data.Length
. Cuando se utilice buffers de datos pre-asignados, el buffer de datos será re-utilizado y dataLength
debe ser utilizado para encontrar el número de bytes actualizados.
Este método requiere un valor de retorno de true o false. Si usted retorna falso, el sistema va a inmediatamente abortar el UnityWebRequest. Si usted devuelve true, el procesamiento va a continuar normalmente.
Muchos de los usuarios avanzados de Unity están constantemente preocupados con reducir los picos de CPU debidos al garbage collection. Para estos usuarios, el sistema UnityWebRequest permite la pre-asignación de un arreglo de byte de código manejado que será utilizado para enviar los datos descargados al callback ReceiveData
de DownloadHandlerScript
Utilizar este método completamente elimina asignaciones de memoria de managed-code cuando utilice clases derivadas de DownloadHandlerScript para capturar datos descargados.
Para hacer que un DownloadHandlerScript
opere con un managed buffer pre-asignado, simplemente proporcione un arreglo byte al constructor del DownloadHandlerScript
.
Tenga en cuenta: EL tamaño del arreglo de byte se limita a la cantidad de datos entregados al callback ReceiveData cada frame. No proporcione un arreglo byte muy pequeño o sus datos llegaran lentos, sobre muchos frames.
Ejemplo
using UnityEngine;
using System.Collections;
public class LoggingDownloadHandler : DownloadHandlerScript {
// Standard scripted download handler - will allocate memory on each ReceiveData callback
public LoggingDownloadHandler(): base() {
}
// Pre-allocated scripted download handler
// Will reuse the supplied byte array to deliver data.
// Eliminates memory allocation.
public LoggingDownloadHandler(byte[] buffer): base(buffer) {
}
// Required by DownloadHandler base class. Called when you address the 'bytes' property.
protected override byte[] GetData() { return null; }
// Called once per frame when data has been received from the network.
protected override bool ReceiveData(byte[] data, int dataLength) {
if(data == null || data.Length < 1) {
Debug.Log("LoggingDownloadHandler :: ReceiveData - received a null/empty buffer");
return false;
}
Debug.Log(string.Format("LoggingDownloadHandler :: ReceiveData - received {0} bytes", dataLength));
return true;
}
// Called when all data has been received from the server and delivered via ReceiveData
protected override void CompleteContent() {
Debug.Log("LoggingDownloadHandler :: CompleteContent - DOWNLOAD COMPLETE!");
}
// Called when a Content-Length header is received from the server.
protected override void ReceiveContentLength(int contentLength) {
Debug.Log(string.Format("LoggingDownloadHandler :: ReceiveContentLength - length {0}", contentLength));
}
}