ASP.NET Core로 Unity WebGL 실행

페이지 업데이트 :
페이지 생성 날짜 :

검증 환경

윈도우
  • 윈도우 11
Unity 에디터
  • 2020.3.25f1
비주얼 스튜디오
  • 비주얼 스튜디오 2022
ASP.NET 코어
  • ASP.NET 코어 6.0
IIS(인터넷 정보 서비스)Internet Information Services (IIS)
  • IIS 10.0

처음에

ASP.NET Core를 실행하는 웹 서버의 Unity에서 게임 출력을 WebGL로 실행하는 방법을 알아봅니다. 게임 프로그램의 경우 아래 팁 단계에서 출력되는 것을 사용하십시오. 게임 예제에서는 Unity Hub에서 만들 수 있는 2D 플랫포머 마이크로게임을 사용합니다.

WebGL 게임을 실행하기 위해 "Uncompressed WebGL", "WebGL compressed with Gzip", "WebGL compressed with Brotli"를 설정하는 방법을 설명합니다. 절차는 모두 동일합니다.

Visual Studio 2022 ASP.NET Core 6.0을 사용하고 있지만 이전 버전도 작동할 수 있습니다. 다만, 초기 코드의 구조는 버전마다 다르기 때문에, 그 차이는 스스로 이해하시기 바랍니다.

ASP.NET 핵심 프로젝트 만들기

시작 메뉴에서 "Visual Studio 2022"를 시작합니다.

새 프로젝트 만들기를 선택합니다.

이번에는 샘플로 "ASP.NET Core Web App"을 선택합니다. ASP.NET Core에서 실행 중인 경우 다른 템플릿을 실행할 수 있지만 빌드 방법에 대해서는 각 템플릿을 따라야 합니다.

프로젝트 이름과 위치를 임의로 설정합니다.

추가 정보는 그대로 둡니다.

프로젝트가 생성되었습니다.

압축되지 않은 WebGL 실행

압축하지 않고 만든 WebGL 프로그램을 준비합니다.

게임이 빠르게 작동하는지 확인

ASP.NET 핵심 에티켓을 따르지 않고 더 적은 설정으로 WebGL 게임을 실행해 보세요.

ASP.NET Core에서는 Unity에서 내보낸 일부 WebGL 파일을 기본 상태로 액세스할 수 없습니다. 액세스할 수 있도록 합니다.

프로그램.cs

Program.cs 프로젝트에서 엽니다. 이전 ASP.NET Core 버전에 Startup.cs 적용됩니다.

코드 맨 위에 네임스페이스를 추가하고 코드에서 app.UseStaticFiles(); 다음을 바꿉니다.

// ここから追加
using Microsoft.AspNetCore.StaticFiles;
// ここまで追加

var builder = WebApplication.CreateBuilder(args);

// --- 省略 ---

app.UseHttpsRedirection();

//app.UseStaticFiles();
// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";

app.UseStaticFiles(new StaticFileOptions()
{
  ContentTypeProvider = provider,
});
// ここまで追加

app.UseRouting();

// --- 省略 ---

.data, 파일에 액세스할 .wasm 때 지정된 Content-Type .

WebGL 배포

Unity의 다음 파일 폴더를 프로젝트에 wwwroot 배치합니다.

  • 인덱스.html
  • 체격
  • 틀데이터

Index.cshtmlindex.html 액세스할 수 있도록 링크를 엽니다.

<!-- 省略 -->

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<!-- 追加 -->
<a href="index.html">index.html</a>

프로그램을 실행하고 게임이 작동하는지 확인하십시오.

Razor 페이지에서 WebGL 프로그램 실행

이전 게임은 정적 HTML 파일에서 실행되었으므로 ASP.NET Core와 관련이 없는 위치에서 실행됩니다. 프로그램 균일성을 위해 그다지 바람직하지 않으므로 HTML 파일의 동작을 Razor Pages로 이동합니다.

프로젝트에서 Pages 폴더를 마우스 오른쪽 단추로 클릭하여 새 항목을 추가합니다.

Razor Page - Empty를 선택합니다. 지정된 특정 이름은 없지만 여기에 WebGL.cshtml 추가됩니다 .

코드가 표시됩니다.

index.html 파일 및 포트 WebGL.cshtml 의 내용을 참조하십시오. link 태그를 배치하는 방법 등 이상한 점이 있습니다 만, 설명의 간결함을 위해 그대로 두겠습니다.

@page
@model UnityPublishWebglAspNetCore.Pages.WebGLModel
@{
}

<div id="unity-container" class="unity-desktop">
  <canvas id="unity-canvas" width=960 height=600></canvas>
  <div id="unity-loading-bar">
    <div id="unity-logo"></div>
    <div id="unity-progress-bar-empty">
      <div id="unity-progress-bar-full"></div>
    </div>
  </div>
  <div id="unity-warning"> </div>
  <div id="unity-footer">
    <div id="unity-webgl-logo"></div>
    <div id="unity-fullscreen-button"></div>
    <div id="unity-build-title">Platformer</div>
  </div>
</div>

@section Scripts {
  <link rel="shortcut icon" href="TemplateData/favicon.ico">
  <link rel="stylesheet" href="TemplateData/style.css">
  <script>
    var container = document.querySelector("#unity-container");
    var canvas = document.querySelector("#unity-canvas");
    var loadingBar = document.querySelector("#unity-loading-bar");
    var progressBarFull = document.querySelector("#unity-progress-bar-full");
    var fullscreenButton = document.querySelector("#unity-fullscreen-button");
    var warningBanner = document.querySelector("#unity-warning");

    // 一時的なメッセージバナー/リボンを数秒間表示するか、
    // type == 'error'の場合はキャンバスの上部に永続的なエラーメッセージを表示します。
    // type == 'warning'の場合、黄色のハイライト色が使用されます。
    // この関数を変更または削除して、重要ではない警告とエラーメッセージがユーザーに表示されるように
    // 視覚的に表示される方法をカスタマイズします。
    function unityShowBanner(msg, type) {
      function updateBannerVisibility() {
        warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
      }
      var div = document.createElement('div');
      div.innerHTML = msg;
      warningBanner.appendChild(div);
      if (type == 'error') div.style = 'background: red; padding: 10px;';
      else {
        if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
        setTimeout(function() {
          warningBanner.removeChild(div);
          updateBannerVisibility();
        }, 5000);
      }
      updateBannerVisibility();
    }

    var buildUrl = "Build";
    var loaderUrl = buildUrl + "/WebGL.loader.js";
    var config = {
      dataUrl: buildUrl + "/WebGL.data",
      frameworkUrl: buildUrl + "/WebGL.framework.js",
      codeUrl: buildUrl + "/WebGL.wasm",
      streamingAssetsUrl: "StreamingAssets",
      companyName: "DefaultCompany",
      productName: "Platformer",
      productVersion: "2.1.0",
      showBanner: unityShowBanner,
    };

    // デフォルトでは、Unity は WebGL キャンバスレンダリングのターゲットサイズを
    // キャンバス要素の DOM サイズ(window.devicePixelRatio でスケーリング)と一致させます。
    // この同期がエンジン内で発生しないようにする場合は、これを false に設定し、
    // 代わりにサイズを大きくします。 キャンバスの DOM サイズと WebGL は、
    // ターゲットサイズを自分でレンダリングします。
    // config.matchWebGLToCanvasSize = false;

    if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
      container.className = "unity-mobile";
      // モバイルデバイスでフィルレートのパフォーマンスを低下させないようにし、
      // モバイルブラウザで低 DPI モードをデフォルト/オーバーライドします。
      config.devicePixelRatio = 1;
      unityShowBanner('WebGL builds are not supported on mobile devices.');
    } else {
      canvas.style.width = "960px";
      canvas.style.height = "600px";
    }
    loadingBar.style.display = "block";

    var script = document.createElement("script");
    script.src = loaderUrl;
    script.onload = () => {
      createUnityInstance(canvas, config, (progress) => {
        progressBarFull.style.width = 100 * progress + "%";
      }).then((unityInstance) => {
        loadingBar.style.display = "none";
        fullscreenButton.onclick = () => {
          unityInstance.SetFullscreen(1);
        };
      }).catch((message) => {
        alert(message);
      });
    };
    document.body.appendChild(script);
  </script>
}

Index.cshtmlWebGL 에 대한 링크를 추가합니다.

<!-- 省略 -->

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<!-- 追加 -->
<ul>
  <li><a href="index.html">index.html</a></li>
  <li><a href="WebGL">WebGL</a></li>
</ul>

프로그램을 실행해 봅니다. 에 따라 WebGL 페이지에 머리글과 바닥글 _Layout.cshtml 이 표시되는 것을 볼 수 있습니다.

WebGL 파일의 위치 변경

WebGL 파일을 바로 아래에 배치했지만 이 메서드는 두 개 이상의 WebGL wwwroot 파일을 배치할 때 덮어씁니다. 이것을 별도의 폴더에 넣고 이동하는 방법을 설명하겠습니다.

먼저 "webgl"이라는 새 폴더를 만들어 거기로 이동합니다. 이동할 두 폴더 Build는 , TemplateData 입니다. index.html 이미 Razor Pages로 이식했으며 안전하게 삭제할 수 있습니다.

WebGL.cshtml 폴더 계층 구조가 심화되었으므로 에 설명된 경로도 심화할 것입니다. 수정은 3줄입니다.

수정 전

<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
    var buildUrl = "Build";

수정 후

<link rel="shortcut icon" href="webgl/TemplateData/favicon.ico">
<link rel="stylesheet" href="webgl/TemplateData/style.css">
    var buildUrl = "webgl/Build";

프로그램을 실행하여 제대로 작동하는지 확인하십시오.

Gzip으로 압축된 WebGL 실행하기

Gzip으로 압축된 파일의 확장자는 .gz , ASP.NET Core에서 처리할 수 있는 파일이며, Unity WebGL Content-Type 과 다르게 처리되며 변환이 필요합니다.

먼저 WebGL 파일 배포 및 페이지를 만듭니다.

WebGL 파일 배치

wwwrootwebgl-gzip Gzip 아래에 폴더를 만들고 Gzip으로 만든 WebGL 파일에서 BuildTemplateData , 폴더를 복사합니다.

Razor 페이지 만들기

WebGLGzip.cshtml 이번에는 압축을 풀었을 때와 동일한 절차를 사용하여 파일을 만듭니다.

코드는 Unity의 출력을 index.html 참조하여 다음과 같습니다. 경로는 WebGL 파일에 대해 이전에 만든 webgl-gzip 폴더와 일치합니다.

@page
@model UnityPublishWebglAspNetCore.Pages.WebGLGzipModel
@{
}

<div id="unity-container" class="unity-desktop">
  <canvas id="unity-canvas" width=960 height=600></canvas>
  <div id="unity-loading-bar">
    <div id="unity-logo"></div>
    <div id="unity-progress-bar-empty">
      <div id="unity-progress-bar-full"></div>
    </div>
  </div>
  <div id="unity-warning"> </div>
  <div id="unity-footer">
    <div id="unity-webgl-logo"></div>
    <div id="unity-fullscreen-button"></div>
    <div id="unity-build-title">Platformer</div>
  </div>
</div>

@section Scripts {
  <link rel="shortcut icon" href="webgl-gzip/TemplateData/favicon.ico">
  <link rel="stylesheet" href="webgl-gzip/TemplateData/style.css">
  <script>
    var container = document.querySelector("#unity-container");
    var canvas = document.querySelector("#unity-canvas");
    var loadingBar = document.querySelector("#unity-loading-bar");
    var progressBarFull = document.querySelector("#unity-progress-bar-full");
    var fullscreenButton = document.querySelector("#unity-fullscreen-button");
    var warningBanner = document.querySelector("#unity-warning");

    // 一時的なメッセージバナー/リボンを数秒間表示するか、
    // type == 'error'の場合はキャンバスの上部に永続的なエラーメッセージを表示します。
    // type == 'warning'の場合、黄色のハイライト色が使用されます。
    // この関数を変更または削除して、重要ではない警告とエラーメッセージがユーザーに表示されるように
    // 視覚的に表示される方法をカスタマイズします。
    function unityShowBanner(msg, type) {
      function updateBannerVisibility() {
        warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
      }
      var div = document.createElement('div');
      div.innerHTML = msg;
      warningBanner.appendChild(div);
      if (type == 'error') div.style = 'background: red; padding: 10px;';
      else {
        if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
        setTimeout(function() {
          warningBanner.removeChild(div);
          updateBannerVisibility();
        }, 5000);
      }
      updateBannerVisibility();
    }

    var buildUrl = "webgl-gzip/Build";
    var loaderUrl = buildUrl + "/WebGL_Gzip.loader.js";
    var config = {
      dataUrl: buildUrl + "/WebGL_Gzip.data.gz",
      frameworkUrl: buildUrl + "/WebGL_Gzip.framework.js.gz",
      codeUrl: buildUrl + "/WebGL_Gzip.wasm.gz",
      streamingAssetsUrl: "StreamingAssets",
      companyName: "DefaultCompany",
      productName: "Platformer",
      productVersion: "2.1.0",
      showBanner: unityShowBanner,
    };

    // デフォルトでは、Unity は WebGL キャンバスレンダリングのターゲットサイズを
    // キャンバス要素の DOM サイズ(window.devicePixelRatio でスケーリング)と一致させます。
    // この同期がエンジン内で発生しないようにする場合は、これを false に設定し、
    // 代わりにサイズを大きくします。 キャンバスの DOM サイズと WebGL は、
    // ターゲットサイズを自分でレンダリングします。
    // config.matchWebGLToCanvasSize = false;

    if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
      container.className = "unity-mobile";
      // モバイルデバイスでフィルレートのパフォーマンスを低下させないようにし、
      // モバイルブラウザで低 DPI モードをデフォルト/オーバーライドします。
      config.devicePixelRatio = 1;
      unityShowBanner('WebGL builds are not supported on mobile devices.');
    } else {
      canvas.style.width = "960px";
      canvas.style.height = "600px";
    }
    loadingBar.style.display = "block";

    var script = document.createElement("script");
    script.src = loaderUrl;
    script.onload = () => {
      createUnityInstance(canvas, config, (progress) => {
        progressBarFull.style.width = 100 * progress + "%";
      }).then((unityInstance) => {
        loadingBar.style.display = "none";
        fullscreenButton.onclick = () => {
          unityInstance.SetFullscreen(1);
        };
      }).catch((message) => {
        alert(message);
      });
    };
    document.body.appendChild(script);
  </script>
}

이 페이지로 이동할 수 있도록 Index.cshtml 수정합니다.

<!-- 省略 -->

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<!-- 追加 -->
<ul>
  <li><a href="index.html">index.html</a></li>
  <li><a href="WebGL">WebGL</a></li>
  <li><a href="WebGLGzip">WebGLGzip</a></li>
</ul>

고정 프로그램.cs

app.UseStaticFiles 메서드를 처리하는 파트를 다음과 같이 수정합니다.

수정 전

// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";

app.UseStaticFiles(new StaticFileOptions()
{
  ContentTypeProvider = provider,
});
// ここまで追加

수정 후

// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";
provider.Mappings[".br"] = "application/octet-stream";   // .br ファイルにアクセスできるように追加
provider.Mappings[".js"] = "application/javascript";     // 後の変換の為に追加

app.UseStaticFiles(new StaticFileOptions()
{
  ContentTypeProvider = provider,
  OnPrepareResponse = context =>
  {
    var path = context.Context.Request.Path.Value;
    var extension = Path.GetExtension(path);

    // 「.gz」「.br」ファイルにアクセスした場合は Content-Type と Content-Encoding を設定する
    if (extension == ".gz" || extension == ".br")
    {
      var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path) ?? "";
      if (provider.TryGetContentType(fileNameWithoutExtension, out string? contentType))
      {
        context.Context.Response.ContentType = contentType;
        context.Context.Response.Headers.Add("Content-Encoding", extension == ".gz" ? "gzip" : "br");
      }
    }
  },
});
// ここまで追加

ASP.NET Core .gz 에서 파일은 Content-Type application/x-gzip . 그대로는 클라이언트의 Unity WebGL이 판단할 수 없기 때문에 .gz , 를 제외한 파일의 확장자에 Content-Type 따라 다시 작성하여 반환합니다. Content-Encoding 필요하기 때문에 gzip 설정도 했습니다.

덧붙여서 Brotli 코드도 함께 넣었으므로 다음 항목의 Brotli 대응에서대로이 코드를 사용할 수 있습니다. Brotli는 또한 .br br Content-Encoding Content-Type . 그러나 ASP.NET Core.br에서는 기본적으로 파일에 액세스 할 수 없으므로 provider.Mappings .br .

그런 다음 디버그를 실행하고 게임이 올바르게 작동하는지 확인하십시오.

올바르게 설정했는데도 게임이 표시되지 않으면 웹 브라우저의 캐시를 지워 쿠키를 지워보세요.

Brotli로 압축된 WebGL 실행하기

절차는 Gzip과 거의 동일하며 Gzip 부분을 Brotli로 대체합니다. 그러나 Brotli(.br) 파일은 ASP.NET Core에서 기본적으로 액세스할 수 없습니다. 접근할 수 있도록 설정해야 하지만, Gzip 당시의 코드를 사용하고 있다면 지원됩니다.

먼저 WebGL 파일 배포 및 페이지를 만듭니다.

WebGL 파일 배치

wwwrootwebgl-brotli 폴더 만들기에서 Brotli로 만든 WebGL 파일의 , 폴더를 BuildTemplateData 복사합니다.

Razor 페이지 만들기

Gzip과 동일한 단계를 사용하여 WebGLBrotli.cshtml 파일을 만듭니다.

코드는 Unity의 출력을 index.html 참조하여 다음과 같습니다. 경로는 WebGL 파일에 대해 이전에 만든 webgl-brotli 폴더와 일치합니다.

@page
@model UnityPublishWebglAspNetCore.Pages.WebGLBrotliModel
@{
}

<div id="unity-container" class="unity-desktop">
  <canvas id="unity-canvas" width=960 height=600></canvas>
  <div id="unity-loading-bar">
    <div id="unity-logo"></div>
    <div id="unity-progress-bar-empty">
      <div id="unity-progress-bar-full"></div>
    </div>
  </div>
  <div id="unity-warning"> </div>
  <div id="unity-footer">
    <div id="unity-webgl-logo"></div>
    <div id="unity-fullscreen-button"></div>
    <div id="unity-build-title">Platformer</div>
  </div>
</div>

@section Scripts {
  <link rel="shortcut icon" href="webgl-brotli/TemplateData/favicon.ico">
  <link rel="stylesheet" href="webgl-brotli/TemplateData/style.css">
  <script>
    var container = document.querySelector("#unity-container");
    var canvas = document.querySelector("#unity-canvas");
    var loadingBar = document.querySelector("#unity-loading-bar");
    var progressBarFull = document.querySelector("#unity-progress-bar-full");
    var fullscreenButton = document.querySelector("#unity-fullscreen-button");
    var warningBanner = document.querySelector("#unity-warning");

    // 一時的なメッセージバナー/リボンを数秒間表示するか、
    // type == 'error'の場合はキャンバスの上部に永続的なエラーメッセージを表示します。
    // type == 'warning'の場合、黄色のハイライト色が使用されます。
    // この関数を変更または削除して、重要ではない警告とエラーメッセージがユーザーに表示されるように
    // 視覚的に表示される方法をカスタマイズします。
    function unityShowBanner(msg, type) {
      function updateBannerVisibility() {
        warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
      }
      var div = document.createElement('div');
      div.innerHTML = msg;
      warningBanner.appendChild(div);
      if (type == 'error') div.style = 'background: red; padding: 10px;';
      else {
        if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
        setTimeout(function() {
          warningBanner.removeChild(div);
          updateBannerVisibility();
        }, 5000);
      }
      updateBannerVisibility();
    }

    var buildUrl = "webgl-brotli/Build";
    var loaderUrl = buildUrl + "/WebGL_Brotli.loader.js";
    var config = {
      dataUrl: buildUrl + "/WebGL_Brotli.data.br",
      frameworkUrl: buildUrl + "/WebGL_Brotli.framework.js.br",
      codeUrl: buildUrl + "/WebGL_Brotli.wasm.br",
      streamingAssetsUrl: "StreamingAssets",
      companyName: "DefaultCompany",
      productName: "Platformer",
      productVersion: "2.1.0",
      showBanner: unityShowBanner,
    };

    // デフォルトでは、Unity は WebGL キャンバスレンダリングのターゲットサイズを
    // キャンバス要素の DOM サイズ(window.devicePixelRatio でスケーリング)と一致させます。
    // この同期がエンジン内で発生しないようにする場合は、これを false に設定し、
    // 代わりにサイズを大きくします。 キャンバスの DOM サイズと WebGL は、
    // ターゲットサイズを自分でレンダリングします。
    // config.matchWebGLToCanvasSize = false;

    if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
      container.className = "unity-mobile";
      // モバイルデバイスでフィルレートのパフォーマンスを低下させないようにし、
      // モバイルブラウザで低 DPI モードをデフォルト/オーバーライドします。
      config.devicePixelRatio = 1;
      unityShowBanner('WebGL builds are not supported on mobile devices.');
    } else {
      canvas.style.width = "960px";
      canvas.style.height = "600px";
    }
    loadingBar.style.display = "block";

    var script = document.createElement("script");
    script.src = loaderUrl;
    script.onload = () => {
      createUnityInstance(canvas, config, (progress) => {
        progressBarFull.style.width = 100 * progress + "%";
      }).then((unityInstance) => {
        loadingBar.style.display = "none";
        fullscreenButton.onclick = () => {
          unityInstance.SetFullscreen(1);
        };
      }).catch((message) => {
        alert(message);
      });
    };
    document.body.appendChild(script);
  </script>
}

이 페이지로 이동할 수 있도록 Index.cshtml 수정합니다.

<!-- 省略 -->

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<!-- 追加 -->
<ul>
  <li><a href="index.html">index.html</a></li>
  <li><a href="WebGL">WebGL</a></li>
  <li><a href="WebGLGzip">WebGLGzip</a></li>
  <li><a href="WebGLBrotli">WebGLBrotli</a></li>
</ul>

고정 프로그램.cs

Gzip이 지원될 때 수정하면 동일한 코드를 사용할 수 있습니다.

수정 후 디버그를 실행하고 게임이 작동하는지 확인하십시오.

올바르게 설정했는데도 게임이 표시되지 않으면 웹 브라우저의 캐시를 지워 쿠키를 지워보세요.

IIS 웹 서버에서 Brotli 파일에 액세스할 때의 증상 이해

Brotli는 기본적으로 IIS에서 지원되지 않으므로 IIS 쪽에서 구성해야 합니다. 고급 설정으로 처리 할 수있는 것 같습니다 만,이 팁에서는 설명하지 않습니다. 아래 링크된 정보를 참조하십시오.

오류 메시지

Unable to load file webgl-brotli/Build/WebGL_Brotli.framework.js.br! Check that the file exists on the remote server. (also check browser Console and Devtools Network tab to debug)