Unity2021.以降のバージョンのUnityWebGL Loaderでプログレスバーを表示する

Unity2021のどのバージョンからはわかりませんが、UnityWebGLLoaderでプログレスバーが表示されなくなりました。そこでプログレスバーを独自に実装する方法の忘備録です。

まず、WebGLでビルドすると以下のシンプルなindex.htmlが作成されます。

```html:index.html
<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Unity WebGL Player | GAME TITLE</title>
  </head>
  <body style="text-align: center">
    <canvas id="unity-canvas" style="width: 960px; height: 540px; background: #231F20"></canvas>
    <script src="Build/WebGL.loader.js"></script>
    <script>
      createUnityInstance(document.querySelector("#unity-canvas"), {
        dataUrl: "Build/WebGL.data",
        frameworkUrl: "Build/WebGL.framework.js",
        codeUrl: "Build/WebGL.wasm",
        streamingAssetsUrl: "StreamingAssets",
        companyName: "Maker Name",
        productName: "Game Title",
        productVersion: "1.00",
      });
    </script>
  </body>
</html>
```
ですがこれをブラウザで読み込んでも、以前のようなプログレスバーが表示されなくなりました。
![UnityWebGK.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/3ee5f344-a111-6218-f159-8943487714ef.jpeg)
↑以前はこういうのが出ていました。
そしてUNITY2021以降のバージョンだとこう↓
![UnityWebGL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/e8174ca3-ea7f-c271-f560-6c66e0e24da0.jpeg)
ユーザーから見ると画面が暗いままでフリーズしたかのような印象を与えてしまうので、あまりイメージが良くありません。じゃあ、UnityWebGLがロード以外何もしていないかというとそういうことはなく、promiseというjavascriptの非同期イベントをまとめたようなオブジェクトを返すようになっています。

まず、\<script>タグ内にの３つのメソッドを書きます

```javascript
function OnLoadSuccess(e) {
  //ロードが成功してUNITYが起動したときの処理
}
function OnLoadFailure(error) {
  //ロードが失敗したときの処理
  console.log("Load Failed :" + error);
}
function OnLoadProgress(e){
  //ロードの進捗
}
```
そしてcreateUnityInstance命令を変数に代入し、第3引数にOnLoadProgressを登録します。
最後にその変数に.then(OnLoadSuccess,OnLoadFailure)を追加します。

```javascript
<script>
      const promise = createUnityInstance(document.querySelector("#unity-canvas"), {
        dataUrl: "Build/WebGL.data",
        frameworkUrl: "Build/WebGL.framework.js",
        codeUrl: "Build/WebGL.wasm",
        streamingAssetsUrl: "StreamingAssets",
        companyName: "Maker Name",
        productName: "Game Title",
        productVersion: "1.00",
      } , OnLoadProgress);

      promise.then(OnLoadSuccess, OnLoadFailure);

      function OnLoadSuccess(e) {
        //ロードが成功してUNITYが起動したときの処理
      }
      function OnLoadFailure(error) {
        //ロードが失敗したときの処理
        console.log("Load Failed :" + error);
      }
      function OnLoadProgress(e){
        //ロードの進捗
      }
</script>
```
これでロードのプログレス状況を獲得する準備ができました。

Html5にprogress という進捗状況を表示する要素があるので、"unity-canvas"の真下に記述します。適当にサイズを大きめすると直前の"text-align: center"のおかげでUnityCanvasの下に進捗状況が表示されます。

```html
<canvas id="unity-canvas" style="width: 960px; height: 540px; background: #231F20"></canvas>
<progress id="progress_bar" min="0" max="1.0" style="width: 960px"></progress>
```
このProgress_barを操作するためにOnLoadSuccess,OnLoadProgressに以下のような記述を書きます。

```javascript
var progressbar = document.getElementById("progress_bar");

function OnLoadSuccess(e) {
  //ロードが成功してUNITYが起動したときの処理
  progressbar.style.display='none';
}
function OnLoadProgress(e){
  //ロードの進捗
  if(progressbar!=null){
    progressbar.setAttribute("value", e);
  }
}
```
これでロード中にプログレスバーが表示され、ゲームが起動すると消えるという処理ができるようになります。

![UnityWebGL2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/bea8c967-6220-667e-a9f8-2c357e6112a6.jpeg)

まとめると一番簡単なのは以下のようなソースになります。
（プログレスバーの表示位置を変えたい場合はCSSで記述してください）

```javascript:index.html
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unity WebGL Player | GameTitle</title>
<style type="text/css"></style>
</head>
<body style="text-align: center">
<canvas id="unity-canvas" style="width: 960px; height: 540px; background: #231F20"></canvas>
<progress id="progress_bar" min="0" max="1.0" value="0.0" style="width: 960px"></progress>
<script src="Build/WebGL.loader.js"></script> 
<script>
      const promise = createUnityInstance(document.querySelector("#unity-canvas"), {
        dataUrl: "Build/WebGL.data",
        frameworkUrl: "Build/WebGL.framework.js",
        codeUrl: "Build/WebGL.wasm",
        streamingAssetsUrl: "StreamingAssets",
        companyName: "Maker Name",
        productName: "Game Title",
        productVersion: "1.00",
      } , OnLoadProgress);

      promise.then(OnLoadSuccess, OnLoadFailure);

    var progressbar = document.getElementById("progress_bar");

    function OnLoadSuccess(e) {
        //ロードが成功してUNITYが起動したときの処理
        progressbar.style.display='none';
    }
    function OnLoadFailure(error) {
        //ロードが失敗したときの処理
        console.log("Load Failed :" + error);
    }
    function OnLoadProgress(e){
        //ロードの進捗
        if(progressbar!=null){
            progressbar.setAttribute("value", e);
        }
}
</script>
</body>
</html>
```