ドキュメント

Unity Engine

Unity Engine

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
    はオーディオファイルをダウンロードするために使用されます。
  • DownloadHandlerMovieTexture
    はビデオファイルをダウンロードするために使用されます。MovieTexture は非推奨であるため、ビデオのダウンロードとムービーの再生には VideoPlayer を使用することをお勧めします。
  • DownloadHandlerScript
    は特殊クラスです。それ自体では何も行いません。ただし、このクラスはユーザー定義のクラスによって継承が可能です。このクラスは UnityWebRequest システムからコールバックを受け取り、ネットワークからデータを取得したときに完全にカスタム処理するために使用します。
API は
DownloadHandlerTexture
のインターフェースに似ています。
UnityWebRequest
には
disposeDownloadHandlerOnDispose
というプロパティがあり、デフォルトは true です。このプロパティが true の場合、UnityWebRequest オブジェクトが破棄されると、アタッチされているダウンロードハンドラーでも Dispose() が呼び出され、オブジェクトが使用できなくなります。ダウンロードハンドラーへの参照を UnityWebRequest へのリファレンスよりも長く保持する場合は、disposeDownloadHandlerOnDispose を false に設定する必要があります。

DownloadHandlerBuffer このダウンロードハンドラーは最も簡単で、たいていのケースを処理できます。このハンドラーは受け取ったデータをネイティブコードバッファーに格納します。ダウンロードが終了すると、バイト配列またはテキスト文字列で、バッファーされたデータにアクセスできます。

例

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
を使用する方が効率的です。

このダウンロードハンドラーは、受信したデータを
UnityEngine.Texture
に格納します。ダウンロードが完了すると、JPEG と PNG を有効な
UnityEngine.Texture objects
にデコードします。
UnityEngine.Texture
のコピーは、
DownloadHandlerTexture
オブジェクトごとに 1 つだけ作成されます。ですから、ガベージコレクションによるパフォーマンスの低下を軽減します。ハンドラーは、バッファリング、解凍、テクスチャの作成をネイティブコードで実行します。さらに、解凍とテクスチャの作成を、メインスレッドでなくワーカースレッドで実行するため、大きなテクスチャをロードするときにフレーム時間を向上させます。
最後に、
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 のアセットバンドルシステムにデータをストリーミングできることです。アセットバンドルシステムが十分なデータを受け取ると、アセットバンドルは
UnityEngine.AssetBundle
オブジェクトとして利用できます。
UnityEngine.AssetBundle
オブジェクトのコピーは 1 つだけ作成されます。これにより、ランタイムメモリの割り当てと、アセットバンドルのロードによるメモリへの影響が大幅に軽減されます。また、完全にダウンロードされていないときにアセットバンドルを部分的に使用することができます。ですから、アセットをストリーミングすることができます。
すべてのダウンロードと解凍はワーカースレッドで行われます。
アセットバンドルは、
DownloadHandlerAssetBundle
オブジェクトをとおしてダウンロードされます。このオブジェクトには、アセットバンドルを取得する特別な
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; } }}

DownloadHandlerAudioClip

このダウンロードハンドラーは、オーディオファイルをダウンロードするために最適化されています。
DownloadHandlerBuffer
を使用して Raw バイトをダウンロードしてから
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 } }}

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 回呼び出されます。
data
引数には、リモートサーバーから受信した Raw バイトが含まれます。また、
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)); }}