LoginSignup
14
5

More than 3 years have passed since last update.

UnityWebRequestでダウンロードの進捗を取得する

Posted at

概要

  • 大きなファイルをダウンロードするときに進捗を出してあげないと画面が固まって見えてしまいユーザーに不親切です
  • UnityWebRequestを使ったダウンロード進捗の取得方法をいくつか紹介します
  • 今回はCoroutineでの例ですが、UniRxやUniTaskに書き換えることも可能です

進捗を%で取得する

progress.gif
進捗を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でも同じ値が取得できます

ダウンロード済みのバイト数を取得する

progress_bytes.gif
ダウンロードしたバイト数を取得します
こちらも同じようにコールバックとして毎フレームバイト数を返しています

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に変わっただけです

コンテンツサイズを取得する

contentsize.gif
ここまでで進捗はわかるようになりましたが、ダウンロードするコンテンツ自体のサイズ自体はわかりません。
そこで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);
        }
    }
}

参考

14
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
5