概要
- 大きなファイルをダウンロードするときに進捗を出してあげないと画面が固まって見えてしまいユーザーに不親切です
- UnityWebRequestを使ったダウンロード進捗の取得方法をいくつか紹介します
- 今回はCoroutineでの例ですが、UniRxやUniTaskに書き換えることも可能です
進捗を%で取得する
進捗を0~1で取得します
ファイルの進捗を取得するには1フレームごとに進捗を返してあげる必要があります
Coroutineを使っているので、毎フレームコールバックで進捗を返すよう実装しています
void Start()
{
StartCoroutine(downloadWithProgress("https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetup.dmg"
,(progress)=>
{
Debug.Log(progress);
}));
}
IEnumerator downloadWithProgress(string url, System.Action<float> progress)
{
using (var request = UnityWebRequest.Get(url))
{
var async = request.SendWebRequest();
while (true)
{
if (request.isHttpError || request.isNetworkError)
{
//エラー
Debug.LogError(request.error);
yield break;
}
if (async.isDone)
{
//正常終了
Debug.Log("DONE!");
yield break;
}
yield return null;
//コールバックとして進捗(0~1)を返す
progress(async.progress);
}
}
}
進捗を取得するasync.progress
の部分はrequest.downloadProgress
でも同じ値が取得できます
ダウンロード済みのバイト数を取得する
ダウンロードしたバイト数を取得します
こちらも同じようにコールバックとして毎フレームバイト数を返しています
void Start()
{
StartCoroutine(downloadWithProgressBytes("https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetup.dmg"
,(progress)=>
{
Debug.Log(progress);
}));
}
IEnumerator downloadWithProgressBytes(string url, System.Action<ulong> progress)
{
using (var request = UnityWebRequest.Get(url))
{
var async = request.SendWebRequest();
while (true)
{
if (request.isHttpError || request.isNetworkError)
{
//エラー
Debug.LogError(request.error);
yield break;
}
if (async.isDone)
{
//正常終了
Debug.Log("DONE!");
yield break;
}
yield return null;
//ダウンロード済みバイト数をコールバックで返す
progress(request.downloadedBytes);
}
}
}
先ほどの例と比較すると返す値がrequest.downloadedBytes
に変わっただけです
コンテンツサイズを取得する
ここまでで進捗はわかるようになりましたが、ダウンロードするコンテンツ自体のサイズ自体はわかりません。
そこでResponseHeader
を利用してコンテンツ自体のサイズを取得します
void Start()
{
StartCoroutine(downloadWithContentLength("https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetup.dmg"
,(downloaded, size)=>
{
Debug.Log(downloaded.ToString() + "/" + size.ToString());
}));
}
IEnumerator downloadWithContentLength(string url, System.Action<ulong,ulong> progress)
{
using(var request = UnityWebRequest.Get(url))
{
var async = request.SendWebRequest();
while(true)
{
if (request.isHttpError || request.isNetworkError)
{
//エラー
Debug.LogError(request.error);
yield break;
}
if(async.isDone)
{
//正常終了
Debug.Log("DONE!");
yield break;
}
yield return null;
ulong size = 0;
var header = request.GetResponseHeader("Content-Length");
//1フレーム目はnullが入りうるのでnullチェックをする
if(header != null)
{
ulong.TryParse(header, out size);
}
//第1引数にダウンロード済みバイト数
//第2引数にコンテンツのサイズを返す
progress(request.downloadedBytes, size);
}
}
}