UnityWebRequest 高级API常用的操作
1. 接收文件或二进制数据
从标准的Http或Https服务端接收简单的文本或二进制数据,可以使用UnityWebRequest.GET方法。这个方法只需要传入获取数据的服务端URL即可。这个功能和标准的WWW的构造方法类似,如下面代码所示:
WWW myWww = new WWW("http://www.myserver.com/foo.txt");
// ... is analogous to ...
UnityWebRequest myWr = UnityWebRequest.Get("http://www.myserver.com/foo.txt");
上面代码的详细流程是这样的:
- 创建一个UnityWebRequest对象,并设置目标URL做为字符串参数,但是没有设置自定义的数据和包头信息
- UnityWebRequest会默认绑定一个标准的DownloadHandlerBuffer对象,当请求完成之后,这个Handler缓存从服务端接收到的数据,这些数据可以在代码中直接使用。
- UnityWebRequest默认不会绑定一个UploadHandler对象,如果你需要的话,可以手动操作。
完整的例子如下所示:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class MyBehaviour : MonoBehaviour {
void Start() {
StartCoroutine(GetText());
}
IEnumerator GetText() {
UnityWebRequest www = UnityWebRequest.Get("http://www.my-server.com");
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError) {
Debug.Log(www.error);
}
else {
// 接收文本数据,并打印到日志中
Debug.Log(www.downloadHandler.text);
// 接收二进制数据
byte[] results = www.downloadHandler.data;
}
}
}
2. 接收Texture
可以使用UnityWebRequest.Texture方法,从远程服务端获取一个Texture文件。这个功能和UnityWebRequest.GET方法非常类似,但是它对下载和存储Texture文件做了优化,提高了处理效率。UnityWebRequest.Texture同样需要一个字符串参数,这个参数就是要下载的资源的URL地址。
详细的处理过程是这样的:
- 创建一个UnityWebRequest对象,并设置目标URL做为字符串参数,但是没有设置自定义的数据和包头信息
- UnityWebRequest会默认绑定一个标准的DownloadHandlerTexture对象,DownloadHandlerTexture是一个特定的Download Handler,它会优化在Unity引擎中使用的图片的存储,相对来说,在下载二进制数据和创建在代码中手动创建Texture对象时,它可以大大的减少内存的再分配。
- UnityWebRequest默认不会绑定一个UploadHandler对象,如果你需要的话,可以手动操作。
完整的例子如下所示:
using UnityEngine; using System.Collections; using UnityEngine.Networking; public class MyBehaviour : MonoBehaviour { void Start() { StartCoroutine(GetTexture()); } IEnumerator GetTexture() { UnityWebRequest www = UnityWebRequestTexture.GetTexture("http://www.my-server.com/image.png"); yield return www.SendWebRequest(); if(www.isNetworkError || www.isHttpError) { Debug.Log(www.error); } else {
//获取并创建Texture Texture myTexture = ((DownloadHandlerTexture)www.downloadHandler).texture; } } }
另外,也可以使用一个工具类,从UnityWebRequest中读取Texture,如下所示:
IEnumerator GetTexture() { UnityWebRequest www = UnityWebRequestTexture.GetTexture("http://www.my-server.com/image.png"); yield return www.SendWebRequest(); //获取Texture对象 Texture myTexture = DownloadHandlerTexture.GetContent(www); }
3. 下载AssetBundle
可以使用UnityWebRequest.GetAssetBundle方法,从远程服务器下载一个AssetBundle,这个方法会在工作线程中,将下载的数据流解码,解压缩,并放到一个内部的buffer之中。这个方法有多种的参数形式,最简单的方式它只需要一个下载AssetBundle文件的URL地址,你也可以选择性的对下载的数据进行checksum校验数据的完整性。另外,如果你想使用AssetBundle的缓存系统,你需要提供一个版本号或一个128位的Hash结构,这和旧系统中WWW.LoadFromCacheOrDownload提供的版本号和128位Hash对象是一样的。
详细的处理过程是这样的:
- 这个方法会创建一个UnityWebRequest,并且设置目标URL和指定Http Get行为,不会再设置其它的标记或自定义包头数据。
- 这个方法会给UnityWebRequest绑定一个DownloadHandlerAssetBundle对象,这个下载Handler有一个特殊的assetBundle属性,它可以保证从下载的数据中,一次性提取出一个完整的AssetBundle,并解码成AssetBundle对象,可以访问这个AssetBundle中的资源。
- 如果你提供一个128位的Hash对象或一个版本号做为参数,这些参数也会被传到DownloadHandlerBundle中,这个下载Handler然后就会使用缓存系统
下面是一个完整的例子:
using UnityEngine; using UnityEngine.Networking; using System.Collections; public class MyBehaviour : MonoBehaviour { void Start() { StartCoroutine(GetAssetBundle()); } IEnumerator GetAssetBundle() { UnityWebRequest www = UnityWebRequest.GetAssetBundle("http://www.my-server.com/myData.unity3d"); yield return www.SendWebRequest(); if(www.isNetworkError || www.isHttpError) { Debug.Log(www.error); } else { AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www); } } }
4. 向服务端发送form数据
在UnityWebRequest中,有两种基本的方法可以向服务端发送HTML form格式的数据,在web开发中,这种方式叫提交一个表单数据。
第一种方式:使用 IMultipartFormSection
为了更好的控制form数据,UnityWebRequest系统提供了一个用户可以实现的接口:IMultipartFormSection,对于一般的应用程序,Unity也提供了两个默认实现的类,MultipartFormDataSection,用于提交form表单数据,MultipartFormFileSection,用于上传文件。
UnityWebRequest.POST的一个重载方式,接收一个List参数,做为该方法的第二个参数,但是这个List的成员必须是IMultipartFormSections的子类,如下面代码所示:
UnityWebRequest.Post(string url, List<IMultipartFormSection> formSections);
详细过程是这样的:
- 这个方法会创建一个新的UnityWebRequest对象,并设置目标URL做为第一个参数,也可以给这次本提交的
IMultipartFormSection
列表form数据在Header中设置合适的Content-Type值。 - 这个方法默认会给UnityWebRequest绑定一个DownloadHandlerBuffer,这样做是为了方便获取服务器响应的数据。
- 和WWWForm Post方法类型,这个HLAPI方法也是按顺序调每一个
IMultipartFormSection
,将它们组装成一个符合RFC 2616标准的multipart form格式的数据。 - 这些预定义好的Form数据会被存储在UploadHanlderRaw对象中,然后把这个对象绑定到UnityWebRequest中,所以,当调用UnityWebRequest.POST方法之后,再修改
IMultipartFormSection
对象的数据,将不会影响到发送给服务器的数据。
如下面代码所示:
using UnityEngine; using UnityEngine.Networking; using System.Collections; using System.Collections.Generic; public class MyBehavior : 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.SendWebRequest(); if (www.isNetworkError || www.isHttpError) { Debug.Log(www.error); } else { Debug.Log("Form upload complete!"); } } }
第二种方式使用WWWForm(遗留的方法)
为了方便从 WWW 系统中迁移,UnityWebRequest允许你使用WWWForm 对象提供form数据,如下面代码所示:
UnityWebRequest.Post(string url, WWWForm formData);
详细过程是这样的:
- 这个方法会创建一个新的UnityWebRequest对象,并设置目标URL做为第一个参数,它也会读取WWWForm中自定义的包头信息,并将它们复制到UnityWebRequest中
- 这个方法默认会给UnityWebRequest绑定一个DownloadHandlerBuffer,这样做是为了方便获取服务器响应的数据。
- 这个方法会读取WWWForm对象中原始的数据,并将它们缓存到一个UploadHandlerRaw对象中,然后将它绑定到UntiyWebRequest中,因此,在调用UnityWebRequest.POST方法之后,再修改原来WWWForm中的数据,将不会改变UntiyWebRequest中的内容。
如下面例子所示:
using UnityEngine; using UnityEngine.Networking; using System.Collections; public 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.SendWebRequest(); if(www.isNetworkError || www.isHttpError) { Debug.Log(www.error); } else { Debug.Log("Form upload complete!"); } } }