Unity Web Request Creating Download Handlers
Choose and create the right DownloadHandler to store data, files, textures, audio, or AssetBundles.
読み終わるまでの所要時間 17 分最終更新 1ヶ月前
DownloadHandlers- は簡易なデータストレージとして使用されます。
DownloadHandlerBuffer - は少ないメモリフットプリントでファイルをダウンロードし、ディスクに保存するために使用されます。
DownloadHandlerFile - は画像をダウンロードするために使用されます。
DownloadHandlerTexture - はアセットバンドルをフェッチするために使用されます。
DownloadHandlerAssetBundle - はオーディオファイルをダウンロードするために使用されます。
DownloadHandlerAudioClip - はビデオファイルをダウンロードするために使用されます。MovieTexture は非推奨であるため、ビデオのダウンロードとムービーの再生には VideoPlayer を使用することをお勧めします。
DownloadHandlerMovieTexture - は特殊クラスです。それ自体では何も行いません。ただし、このクラスはユーザー定義のクラスによって継承が可能です。このクラスは UnityWebRequest システムからコールバックを受け取り、ネットワークからデータを取得したときに完全にカスタム処理するために使用します。
DownloadHandlerScript
API は のインターフェースに似ています。
DownloadHandlerTextureUnityWebRequestdisposeDownloadHandlerOnDisposeDownloadHandlerBuffer このダウンロードハンドラーは最も簡単で、たいていのケースを処理できます。このハンドラーは受け取ったデータをネイティブコードバッファーに格納します。ダウンロードが終了すると、バイト配列またはテキスト文字列で、バッファーされたデータにアクセスできます。
例
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; } }}
DownloadHandlerFile これは大きなファイル用の特別なダウンロードハンドラーです。ダウンロードされたバイトを直接ファイルに書き込むので、ダウンロードするファイルのサイズに関係なくメモリの使用量は少なくなります。他のダウンロードハンドラーとの違いは、このデータは取り出すことができず、すべてのデータはファイルに保存されます。
例
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); }}
DownloadHandlerTexture DownloadHandlerBuffer
を使用して画像ファイルをダウンロードし、それから Texture.LoadImage
を使用して Raw バイトからテクスチャを作成する代わりに、DownloadHandlerTexture
を使用する方が効率的です。
DownloadHandlerBufferTexture.LoadImageDownloadHandlerTextureこのダウンロードハンドラーは、受信したデータを に格納します。ダウンロードが完了すると、JPEG と PNG を有効な にデコードします。 のコピーは、 オブジェクトごとに 1 つだけ作成されます。ですから、ガベージコレクションによるパフォーマンスの低下を軽減します。ハンドラーは、バッファリング、解凍、テクスチャの作成をネイティブコードで実行します。さらに、解凍とテクスチャの作成を、メインスレッドでなくワーカースレッドで実行するため、大きなテクスチャをロードするときにフレーム時間を向上させます。
UnityEngine.TextureUnityEngine.Texture objectsUnityEngine.TextureDownloadHandlerTexture最後に、 は、最終的にテクスチャ自体を作成するときにのみマネージドのメモリを割り当てます。このため、スクリプトでバイトからテクスチャへの変換を実行する際のガベージコレクションのオーバーヘッドを排除します。
DownloadHandlerTexture例
以下の例では、PNG ファイルをインターネットからダウンロードし、スプライトに変換し、画像 に割り当てます。
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; } }}
DownloadHandlerAssetBundle
この特化したダウンロードハンドラーの利点は、Unity のアセットバンドルシステムにデータをストリーミングできることです。アセットバンドルシステムが十分なデータを受け取ると、アセットバンドルは オブジェクトとして利用できます。 オブジェクトのコピーは 1 つだけ作成されます。これにより、ランタイムメモリの割り当てと、アセットバンドルのロードによるメモリへの影響が大幅に軽減されます。また、完全にダウンロードされていないときにアセットバンドルを部分的に使用することができます。ですから、アセットをストリーミングすることができます。
UnityEngine.AssetBundleUnityEngine.AssetBundleすべてのダウンロードと解凍はワーカースレッドで行われます。
アセットバンドルは、 オブジェクトをとおしてダウンロードされます。このオブジェクトには、アセットバンドルを取得する特別な プロパティがあります。
DownloadHandlerAssetBundleassetBundleアセットバンドルシステムの仕組みにより、すべてのアセットバンドルには関連付けられたアドレスが必要です。一般的には、これはアセットバンドルが位置する名目上の 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; } }}
DownloadHandlerAudioClip
このダウンロードハンドラーは、オーディオファイルをダウンロードするために最適化されています。 を使用して Raw バイトをダウンロードしてから を作成する代わりに、このダウンロードハンドラーを使用してより便利に処理できます。
DownloadHandlerBufferAudioClip例
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 } }}
DownloadHandlerScript
ダウンロードしたデータの処理を完全に制御する必要があるユーザーのために、Unity は クラスを提供します。
DownloadHandlerScriptデフォルトでは、このクラスのインスタンスは何も行いません。ただし、 から独自のクラスを派生させる場合、特定の関数をオーバーライドして、ネットワークからデータが到着するときコールバックを受け取るためにその関数を使用します。
DownloadHandlerScript注意実際のダウンロードはワーカースレッド上で行われますが、すべての コールバックはメインスレッド上で動作します。これらのコールバック中に負荷の高い計算操作を行なわないでください。
DownloadHandlerScriptオーバーライドする関数
ReceiveContentLength()
protected void ReceiveContentLength(long contentLength);
この関数は、Content Length ヘッダーが受信されたときに呼び出されます。UnityWebRequest の処理中にサーバーが 1つ以上のリダイレクト応答を送信すると、このコールバックは複数回発生することがあります。
OnContentComplete()
protected void OnContentComplete();
この関数は UnityWebRequest がサーバーからすべてのデータを完全にダウンロードし、それを ReceiveData コールバックに転送したときに呼び出されます。
ReceiveData()
protected bool ReceiveData(byte[] data, long dataLength);
この関数は、リモートサーバーからデータを受信した後に、フレームごとに 1 回呼び出されます。 引数には、リモートサーバーから受信した Raw バイトが含まれます。また、 はデータ配列内の新しいデータの長さを示します。
datadataLength事前に割り当てられたデータバッファを使用しない場合、システムはこのコールバックを呼び出すたびに新しいバイト配列を作成し、 は常に と等しくなります。事前に割り当てられたデータバッファを使用する場合は、データバッファが再利用され、更新されたバイト数を見つけるために を使用する必要があります。
dataLengthdata.LengthdataLengthこの関数には、true または false のいずれかの戻り値が必要です。false を返すと、システムは直ちに UnityWebRequest を中止します。true を返すと、処理は正常に続行されます。
ガーベージコレクションオーバーヘッドの回避 もっと上級レベルの Unity ユーザーの多くは、ガベージコレクションのために CPU スパイクを減らすことを気にかけています。これらのユーザーのために、UnityWebRequest システムは、ダウンロードされたデータを DownloadHandlerScript の ReceiveData
コールバックに配信するために使用されるマネージドのコードのバイト配列の事前割り当てを許可します。
ReceiveDataこの関数を使用すると、DownloadHandlerScript 派生クラスを使用してダウンロードしたデータを取得するときに、マネージドのコードのメモリ割り当てを完全に排除します。
DownloadHandlerScriptDownloadHandlerScript注意バイト配列のサイズは、各フレームで 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)); }}