本日は .Net の小ネタ枠です。
HttpClientを使ってUnityでインターネット上のファイルをダウンロードする方法を記事にします。
HttpClient
.Net で提供されている URL から HTTP 応答を受信するためのクラスです。
docs.microsoft.com
実装例
指定のURLからStreamingAssetsフォルダにファイルをダウンロードするサンプルスクリプトを作成しました。
・HttpGet.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.IO; // HttpClient利用のため using System.Net; using System.Net.Http; public class HttpGet : MonoBehaviour { /// <summary> /// ダウンロード完了時イベント /// </summary> public Action<string> GetComplete; /// <summary> /// ダウンロード失敗時イベント /// </summary> public Action GetFailed; /// <summary> /// 指定URLのファイルをダウンロードする /// </summary> /// <param name="url"></param> public async void AsyncHttpGet(string url) { // URL文字列からURIが作成可能か Uri uriResult; if (!Uri.TryCreate(url, UriKind.Absolute, out uriResult)) { // URIが作成できなければ失敗 GetFailed?.Invoke(); return; } // URL文字列からファイル名を取得する string fileName = Path.GetFileName(url); // HTTP GET のリクエストメッセージを作成する HttpClient httpClient = new HttpClient(); HttpRequestMessage request = new HttpRequestMessage { Method = HttpMethod.Get, RequestUri = uriResult }; // リクエストの実行 HttpResponseMessage response = await httpClient.SendAsync(request); if (response.StatusCode == HttpStatusCode.OK) { // レスポンスコードが成功(200)の場合 // バイト配列をファイルとして書き出す byte[] contentByteData = await response.Content.ReadAsByteArrayAsync(); string saveFilePath = GetSaveFilePath(fileName); File.WriteAllBytes(saveFilePath, contentByteData); // ダウンロード完了イベントを実行 GetComplete?.Invoke(saveFilePath); } else { // レスポンスコードが成功以外の場合 Debug.LogError("HttpGet Error : " + response.StatusCode); // ダウンロード失敗イベントを実行 GetFailed?.Invoke(); } } /// <summary> /// 保存先のファイルパスを生成する /// </summary> /// <param name="filename"></param> /// <returns></returns> private string GetSaveFilePath(string filename) { // ディレクトリの保存先を指定する #if WINDOWS_UWP // HoloLens上での動作の場合、LocalAppData/AppName/LocalStateフォルダを参照する string directory = Windows.Storage.ApplicationData.Current.LocalFolder.Path; #else // Unity上での動作の場合、Assets/StreamingAssetsフォルダを参照する string directory = UnityEngine.Application.streamingAssetsPath; #endif return Path.Combine(directory, filename); } }
シーンの適当なオブジェクトにスクリプトを設定します。
更に本スクリプトを Editor 上からも直接実行可能なように以下の HttpGet のエディター拡張スクリプトを作成しました。
・HttpGetEditor.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; // 拡張するクラスを指定する [CustomEditor(typeof(HttpGet))] public class HttpGetEditor : Editor { private string inputText; // GUIの表示関数をオーバーライドする public override void OnInspectorGUI() { // 元のインスペクター部分を表示 base.OnInspectorGUI(); // targetを変換して対象スクリプトの参照を取得する HttpGet targetScript = target as HttpGet; // public関数を実行するボタンの作成 if (GUILayout.Button("AsyncHttpGetの実行")) { targetScript.AsyncHttpGet(inputText); } inputText = EditorGUILayout.TextField("URL", inputText); } } #endif
本スクリプトを作成すると、以下の通り、HttpGet の Inspector にURLの入力欄と関数の実行ボタンが追加されます。
動作確認
エディター上で動作確認を行います。
Assets フォルダに StreamingAssets フォルダを作成し、シーンを再生します。
URLに以下のサンプル GLB ファイルのアドレスを指定し、関数の実行ボタンをクリックします。
https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/Duck/glTF-Binary/Duck.glb
成功すると、StreamingAssets フォルダにファイルがダウンロードされます。