包含此页的版本:
不含此页的版本:
有几种类型DownloadHandlers:
DownloadHandlerBuffer用于简单的数据存储。DownloadHandlerFile用于以低内存占用下载文件并将其保存到磁盘。DownloadHandlerTexture用于下载图像。DownloadHandlerAssetBundle用于获取资产包。DownloadHandlerAudioClip用于下载音频文件。DownloadHandlerMovieTexture用于下载视频文件。建议使用 VideoPlayer 进行视频下载和电影播放,因为 MovieTexture 已弃用。DownloadHandlerScript是一个特殊的班级。它本身什么也没做。但是,此类可以由用户定义的类继承。此类从 UnityWebRequest 系统接收回调,然后可用于在数据从网络到达时对其执行完全自定义的处理。API 类似于DownloadHandlerTexture的界面。
UnityWebRequest有一个属性disposeDownloadHandlerOnDispose,默认为 true。如果此属性为 true,则在释放 UnityWebRequest 对象时,还将在附加的下载处理程序上调用 Dispose(),使其无用。如果保留对下载处理程序的引用的时间长于对 UnityWebRequest 的引用,则应将 disposeDownloadHandlerOnDispose 设置为 false。
此下载处理程序是最简单的,可处理大多数用例。它将接收到的数据存储在本机代码缓冲区中。下载完成后,您可以以字节数组或文本字符串的形式访问缓冲数据。
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class MyBehaviour : MonoBehaviour {
void Start() {
StartCoroutine(GetText());
}
IEnumerator GetText() {
UnityWebRequest www = new UnityWebRequest("https://www.my-server.com");
www.downloadHandler = new DownloadHandlerBuffer();
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success) {
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;
}
}
}
这是用于大文件的特殊下载处理程序。它将下载的字节直接写入文件,因此无论下载的文件大小如何,内存使用率都很低。与其他下载处理程序的区别在于,您无法从此下载处理程序中获取数据,所有数据都保存到一个文件中。
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class FileDownloader : MonoBehaviour {
void Start () {
StartCoroutine(DownloadFile());
}
IEnumerator DownloadFile() {
var uwr = new UnityWebRequest("https://unity3d.com/", UnityWebRequest.kHttpVerbGET);
string path = Path.Combine(Application.persistentDataPath, "unity3d.html");
uwr.downloadHandler = new DownloadHandlerFile(path);
yield return uwr.SendWebRequest();
if (uwr.result != UnityWebRequest.Result.Success)
Debug.LogError(uwr.error);
else
Debug.Log("File successfully downloaded and saved to " + path);
}
}
而不是使用DownloadHandlerBuffer下载图像文件,然后使用Texture.LoadImage,使用起来效率更高DownloadHandlerTexture.
此下载处理程序将接收到的数据存储在UnityEngine.Texture.下载完成后,它会将 JPEG 和 PNG 解码为有效的UnityEngine.Texture objects.只有一份UnityEngine.Texture是根据DownloadHandlerTexture对象。这减少了垃圾回收对性能的影响。处理程序在本机代码中执行缓冲、解压缩和纹理创建。此外,解压缩和纹理创建是在工作线程而不是主线程上执行的,这可以缩短加载大型纹理时的帧时间。
最后DownloadHandlerTexture仅在最终创建纹理本身时分配托管内存,这消除了与在脚本中执行字节到纹理转换相关的垃圾回收开销。
以下示例从 Internet 下载 PNG 文件,将其转换为精灵A 2D 图形对象。如果你习惯于在3D中工作,精灵本质上只是标准纹理,但有一些特殊的技术可以组合和管理精灵纹理,以提高开发过程中的效率和便利性。更多信息
请参阅术语表,并将其分配给图像:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Collections;
[RequireComponent(typeof(Image))]
public class ImageDownloader : MonoBehaviour {
Image _img;
void Start () {
_img = GetComponent<UnityEngine.UI.Image>();
Download("https://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.SendWebRequest();
if (wr.result == UnityWebRequest.Result.Success) {
Texture2D t = texDl.texture;
Sprite s = Sprite.Create(t, new Rect(0, 0, t.width, t.height),
Vector2.zero, 1f);
_img.sprite = s;
}
}
}
这个专门的下载处理程序的优点是它能够将数据流式传输到 Unity 的 AssetBundle 系统。一旦 AssetBundle 系统收到足够的数据,AssetBundle 就可以作为UnityEngine.AssetBundle对象。只有一份UnityEngine.AssetBundle对象。这大大减少了运行时内存分配以及加载AssetBundle的内存影响。它还允许在未完全下载的情况下部分使用资产包,因此您可以流式传输资产。
所有下载和解压缩都发生在工作线程上。
AssetBundle 通过DownloadHandlerAssetBundle对象,它有一个特殊的assetBundle属性来检索 AssetBundle。
由于 AssetBundle 系统的工作方式,所有 AssetBundle 都必须有一个与之关联的地址。通常,这是它们所在的名义 URL(即任何重定向之前的 URL)。在几乎所有情况下,您都应传入与传递给 UnityWebRequest 相同的 URL。使用高级 API (HLAPI) 时,这是为您完成的。
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class MyBehaviour : MonoBehaviour {
void Start() {
StartCoroutine(GetAssetBundle());
}
IEnumerator GetAssetBundle() {
UnityWebRequest www = new UnityWebRequest("https://www.my-server.com");
DownloadHandlerAssetBundle handler = new DownloadHandlerAssetBundle(www.url, uint.MaxValue);
www.downloadHandler = handler;
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success) {
Debug.Log(www.error);
}
else {
// Extracts AssetBundle
AssetBundle bundle = handler.assetBundle;
}
}
}
此下载处理程序针对下载音频文件进行了优化。而不是使用DownloadHandlerBuffer然后创建AudioClip其中,您可以使用此下载处理程序以更方便的方式完成此作。
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class AudioDownloader : MonoBehaviour {
void Start () {
StartCoroutine(GetAudioClip());
}
IEnumerator GetAudioClip() {
using (var uwr = UnityWebRequestMultimedia.GetAudioClip("https://myserver.com/mysound.ogg", AudioType.OGGVORBIS)) {
yield return uwr.SendWebRequest();
if (uwr.result != UnityWebRequest.Result.Success) {
Debug.LogError(uwr.error);
yield break;
}
AudioClip clip = DownloadHandlerAudioClip.GetContent(uwr);
// use audio clip
}
}
}
对于需要完全控制下载数据处理的用户,Unity 提供了DownloadHandlerScript类。
默认情况下,此类的实例不执行任何作。但是,如果您从DownloadHandlerScript,您可以覆盖某些函数,并在数据从网络到达时使用它们来接收回调。
注意:实际下载发生在工作线程上,但所有DownloadHandlerScript回调在主线程上运行。避免在这些回调期间执行计算量大的作。
protected void ReceiveContentLength(long contentLength);
收到 Content-Length 标头时调用此函数。请注意,如果您的服务器在处理 UnityWebRequest 的过程中发送一个或多个重定向响应,则此回调可能会多次发生。
protected void OnContentComplete();
当 UnityWebRequest 从服务器完全下载所有数据,并将所有接收到的数据转发到 ReceiveData 回调时,将调用此函数。
protected bool ReceiveData(byte[] data, long dataLength);
此函数在数据从远程服务器到达后调用,每帧调用一次。这data参数包含从远程服务器接收的原始字节,并且dataLength表示数据数组中新数据的长度。
当不使用预分配的数据缓冲区时,系统每次调用此回调时都会创建一个新的字节数组,并且dataLength始终等于data.Length.使用预分配的数据缓冲区时,将重复使用数据缓冲区,并且dataLength必须用于查找更新的字节数。
此函数需要返回值 true 或 false。如果返回 false,系统会立即中止 UnityWebRequest。如果返回 true,则处理将继续正常。
Unity 的许多更高级的用户都关心减少由于垃圾收集而导致的 CPU 峰值。对于这些用户,UnityWebRequest 系统允许预分配托管代码字节数组,该数组用于将下载的数据传送到 DownloadHandlerScript 的ReceiveData回调。
使用此函数可以完全消除使用 DownloadHandlerScript 派生类捕获下载数据时的托管代码内存分配。
要制作一个DownloadHandlerScript使用预先分配的托管缓冲区进行作,向 的构造函数提供字节数组DownloadHandlerScript.
注意:字节数组的大小限制了每帧传送到 ReceiveData 回调的数据量。如果数据在许多帧中缓慢到达,则可能提供了太小的字节数组。
using UnityEngine;
using UnityEngine.Networking;
public class LoggingDownloadHandler : DownloadHandlerScript {
// Standard scripted download handler - allocates memory on each ReceiveData callback
public LoggingDownloadHandler(): base() {
}
// Pre-allocated scripted download handler
// reuses 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 ReceiveContentLengthHeader(ulong contentLength) {
Debug.Log(string.Format("LoggingDownloadHandler :: ReceiveContentLength - length {0}", contentLength));
}
}