Chạy Unity WebGL với ASP.NET Core

Trang Cập Nhật :
Ngày tạo trang :

Môi trường xác minh

Windows
  • cửa sổ 11
Biên tập viên Unity
  • 2020.3.25f1
Visual Studio
  • Visual Studio 2022
Lõi ASP.NET
  • ASP.NET lõi 6.0
Dịch vụ thông tin Internet (IIS)
  • IIS 10,0

Lúc đầu

Tìm hiểu cách chạy đầu ra trò chơi dưới dạng WebGL trong Unity trên máy chủ web chạy ASP.NET Core. Đối với các chương trình trò chơi, hãy sử dụng các chương trình đầu ra trong các bước mẹo bên dưới. Ví dụ trò chơi sử dụng Microgame 2D Platformer, có thể được tạo từ Unity Hub.

Tôi sẽ giải thích cách thiết lập "WebGL không nén", "WebGL nén bằng Gzip" và "WebGL nén bằng Brotli" để chạy các trò chơi WebGL. Thủ tục là giống nhau cho tất cả chúng.

Chúng tôi đang sử dụng Visual Studio 2022 ASP.NET Core 6.0, nhưng các phiên bản cũ hơn có thể sẽ hoạt động. Tuy nhiên, cấu trúc của mã ban đầu là khác nhau đối với mỗi phiên bản, vì vậy hãy tự hiểu sự khác biệt.

Tạo một dự án cốt lõi ASP.NET

Khởi chạy "Visual Studio 2022" từ menu bắt đầu.

Chọn Tạo dự án mới.

Lần này, chọn "ASP.NET Core Web App" làm mẫu. Nếu bạn đang chạy trên ASP.NET Core, bạn có thể chạy các mẫu khác, nhưng bạn sẽ cần phải làm theo từng mẫu về cách xây dựng nó.

Đặt tên và vị trí dự án một cách tùy ý.

Để nguyên thông tin bổ sung.

Dự án đã được tạo ra.

Chạy WebGL không nén

Chuẩn bị một chương trình WebGL được tạo mà không nén.

Đảm bảo trò chơi hoạt động nhanh chóng

ASP.NET Thử chạy trò chơi WebGL với ít cài đặt hơn mà không tuân theo nghi thức cốt lõi.

Trong ASP.NET Core, bạn không thể truy cập một số tệp WebGL do Unity phát ra ở trạng thái mặc định. Làm cho điều này có thể truy cập được.

Chương trình.cs

Mở từ dự án của bạn Program.cs . Áp dụng cho các phiên bản Startup.cs ASP.NET Core trước đó .

Thêm không gian tên vào đầu mã và thay thế phần sau trong mã 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, để khi một tệp được truy cập, .wasm nó có thể được trả về máy khách với Content-Type tệp .

Triển khai WebGL

Đặt các thư mục tệp sau từ Unity trong dự án wwwroot của bạn .

  • chỉ số.html
  • Xây dựng
  • Dữ liệu mẫu

Index.cshtmlindex.html Mở liên kết để bạn có thể truy cập nó.

<!-- 省略 -->

<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>

Chạy chương trình và đảm bảo trò chơi hoạt động.

Chạy chương trình WebGL trên trang Razor

Trò chơi trước chạy trên một tệp HTML tĩnh, vì vậy nó chạy ở một nơi không liên quan gì đến ASP.NET Core. Nó không phải là rất mong muốn cho tính đồng nhất của chương trình, vì vậy chúng tôi sẽ di chuyển hành vi của tệp HTML sang Razor Pages.

Nhấp chuột phải vào thư mục Trang từ dự án của bạn để thêm mục mới.

Chọn Razor Page - Empty. Không có tên cụ thể được chỉ định, nhưng nó được thêm vào đây WebGL.cshtml .

Mã được hiển thị.

index.html Tham khảo nội dung của file và port đến WebGL.cshtml . link Có một số điểm lạ, chẳng hạn như cách đặt thẻ, nhưng tôi sẽ để nó như vậy vì mục đích giải thích đơn giản.

@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 Thêm liên kết đến .

<!-- 省略 -->

<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>

Cố gắng chạy chương trình. Bạn có thể thấy rằng đầu trang và chân trang được hiển thị trên trang _Layout.cshtml WebGL theo .

Thay đổi vị trí của tệp WebGL

Tôi đã đặt tệp WebGL ngay dưới , nhưng phương pháp này sẽ ghi đè lên nó khi bạn đặt hai hoặc nhiều tệp WebGL wwwroot . Tôi sẽ giải thích làm thế nào để đặt nó trong các thư mục riêng biệt và di chuyển nó.

Trước hết, tạo một thư mục mới có tên là "webgl" và di chuyển nó đến đó. Hai thư mục Buildcần di chuyển là , TemplateData . index.html Tôi đã chuyển nó sang Razor Pages và có thể xóa nó một cách an toàn.

WebGL.cshtml chúng tôi đã đào sâu hệ thống phân cấp thư mục, chúng tôi cũng sẽ đào sâu đường dẫn được mô tả trong . Hiệu chỉnh là 3 dòng.

Trước khi chỉnh sửa

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

Sau khi chỉnh sửa

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

Chạy chương trình để xem nó có hoạt động đúng không.

Chạy WebGL nén bằng Gzip

Phần mở rộng của tệp được nén bởi Gzip là , và nó là .gz một tệp có thể được xử lý bởi ASP.NET Core, Unity WebGL Content-Type và được xử lý khác nhau và yêu cầu chuyển đổi.

Đầu tiên, tạo trang và triển khai tệp WebGL.

Vị trí tệp WebGL

wwwrootwebgl-gzip Tạo một thư mục trong Gzip và sao chép thư mục , từ tệp BuildTemplateData WebGL bạn đã tạo bằng Gzip.

Tạo một trang dao cạo

Lần WebGLGzip.cshtml này tạo tệp bằng quy trình tương tự như khi không nén.

Mã như sau với tham chiếu đến Đầu ra trong index.html Unity. Đường dẫn khớp với thư mục bạn đã tạo webgl-gzip trước đó cho các tệp WebGL.

@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>
}

Sửa đổi để cho phép điều hướng đến Index.cshtml trang này.

<!-- 省略 -->

<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>

Chương trình sửa chữa.cs

app.UseStaticFiles Sửa đổi phần đang xử lý phương thức như sau.

Trước khi chỉnh sửa

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

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

Sau khi chỉnh sửa

// ここから追加
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");
      }
    }
  },
});
// ここまで追加

Trong ASP.NET Core .gz , file Content-Type application/x-gzip trả về với . Như hiện tại, Unity WebGL trên máy khách không thể xác định nó, vì vậy .gz tôi viết lại và trả về nó theo Content-Type phần mở rộng của tệp loại trừ . Content-Encoding Tôi cũng đặt nó vì nó gzip là cần thiết.

Nhân tiện, tôi cũng đặt mã Brotli lại với nhau, vì vậy bạn có thể sử dụng mã này như trong thư từ Brotli của mục tiếp theo. Brotli cũng .br đặt viết lại Content-Encoding br để phù hợp với Content-Type phần mở rộng của tệp mà không có tệp . Tuy nhiên, tệp không thể truy cập được theo mặc định trong ASP.NET Core,.br vì vậy provider.Mappings tôi đã thêm nó với .br .

Sau đó, chạy gỡ lỗi và kiểm tra xem trò chơi có hoạt động chính xác không.

Nếu bạn đã thiết lập đúng cách và trò chơi vẫn không hiển thị, hãy thử xóa bộ nhớ cache của trình duyệt web để xóa cookie.

Chạy WebGL nén với Brotli

Quy trình này gần giống như Gzip, thay thế phần Gzip bằng Brotli. Tuy nhiên, tệp Brotli (.br) không thể truy cập theo mặc định trong ASP.NET Core. Bạn cần cấu hình nó để bạn có thể truy cập nó, nhưng nếu bạn đang sử dụng mã tại thời điểm Gzip, nó được hỗ trợ.

Đầu tiên, tạo trang và triển khai tệp WebGL.

Vị trí tệp WebGL

wwwrootwebgl-brotli Trong Tạo thư mục, sao chép thư mục , từ tệp WebGL bạn đã BuildTemplateData tạo bằng Brotli.

Tạo một trang dao cạo

Tạo tệp bằng các WebGLBrotli.cshtml bước tương tự như đối với Gzip.

Mã như sau với tham chiếu đến Đầu ra trong index.html Unity. Đường dẫn khớp với thư mục bạn đã tạo webgl-brotli trước đó cho các tệp WebGL.

@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>
}

Sửa đổi để cho phép điều hướng đến Index.cshtml trang này.

<!-- 省略 -->

<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>

Chương trình sửa chữa.cs

Nếu bạn sửa đổi nó khi Gzip được hỗ trợ, bạn có thể sử dụng cùng một mã.

Sau khi sửa nó, chạy gỡ lỗi và kiểm tra xem trò chơi có hoạt động không.

Nếu bạn đã thiết lập đúng cách và trò chơi vẫn không hiển thị, hãy thử xóa bộ nhớ cache của trình duyệt web để xóa cookie.

Hiểu các triệu chứng khi truy cập tệp Brotli trên máy chủ web IIS

Brotli không được IIS hỗ trợ theo mặc định, vì vậy cấu hình ở phía IIS là bắt buộc. Có vẻ như nó có thể được xử lý bằng cách thực hiện các cài đặt nâng cao, nhưng tôi sẽ không giải thích nó trong mẹo này. Vui lòng tham khảo thông tin được liên kết bên dưới.

thông báo lỗi

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)