הפעלת Unity WebGL עם ASP.NET Core
סביבת אימות
- חלונות
-
- חלונות 11
- עורך Unity
-
- 2020.3.25F1
- Visual Studio
-
- Visual Studio 2022
- ASP.NET Core
-
- ASP.NET Core 6.0
- Internet Information Services (IIS)
-
- IIS 10.0
בהתחלה
למד כיצד להפעיל פלט משחק כ- WebGL ב- Unity בשרת אינטרנט שבו פועל ASP.NET Core. עבור תוכניות משחק, השתמש בפלט 'אלה' בשלבי העצות הבאים. דוגמת המשחק משתמשת במיקרו-משחק 2D Platformer שניתן ליצור מ-Unity Hub.
אני אסביר כיצד להגדיר "WebGL לא דחוס", "WebGL דחוס עם Gzip", ו "WebGL דחוס עם Brotli" כדי להפעיל משחקי WebGL. ההליך זהה עבור כולם.
אנו משתמשים ב- 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, אין באפשרותך לגשת לקובצי WebGL מסוימים הנפלטים על-ידי Unity במצב ברירת המחדל. הפוך את זה לנגיש.
בתכנית.cs
פתח מתוך הפרויקט שלך Program.cs
. חל על גירסאות Startup.cs
קודמות ASP.NET Core .
הוסף מרחב שמות לראש הקוד והחלף את הטקסט הבא בקוד 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.cshtml
index.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>
הפעל את התוכנית וודא שהמשחק פועל.
הפעלת תוכנית WebGL בדף סכין גילוח
המשחק הקודם רץ על קובץ HTML סטטי, כך שהוא פועל במקום שאין לו שום קשר עם ASP.NET Core. זה לא מאוד רצוי עבור אחידות התוכנית, אז נעביר את ההתנהגות של קובץ HTML לדפי גילוח.
לחץ באמצעות לחצן העכבר הימני על התיקיה Pages מהפרויקט כדי להוסיף פריט חדש.
בחר דף תער - ריק. לא צוין שם מסוים, אך הוא נוסף כאן 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.cshtml
WebGL
הוסף קישור אל .
<!-- 省略 -->
<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>
נסה להפעיל את התוכנית. ניתן לראות שהכותרת העליונה והתחתונה _Layout.cshtml
מוצגות בדף WebGL לפי .
שינוי המיקום של קבצי WebGL
מיקמתי את קובץ WebGL ישירות מתחת ל- , אך שיטה זו תחליף אותו כאשר תמקם שני קבצי WebGL wwwroot
או יותר.
אני אסביר איך לשים את זה בתיקיות נפרדות ולהעביר את זה.
קודם כל, ליצור תיקייה חדשה בשם "webgl" ולהעביר אותו לשם. שתי התיקיות שיש Build
להעביר הן , TemplateData
.
index.html
כבר העברתי אותו לדפי גילוח ואני יכול למחוק אותו בבטחה.
מכיוון 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";
הפעל את התוכנית כדי לראות אם היא פועלת כראוי.
הפעלת WebGL דחוס עם Gzip
הסיומת של הקובץ הדחוס על ידי Gzip היא .gz
, וזה קובץ שניתן לטפל בו על ידי ASP.NET Core,
Unity WebGL Content-Type
ומטופלים בצורה שונה ודורשים המרה.
ראשית, צור פריסת קבצים ודף WebGL.
מיקום קובץ WebGL
wwwroot
webgl-gzip
צור תיקייה תחת Gzip והעתק את התיקיה , מקובץ Build
TemplateData
WebGL שיצרת באמצעות Gzip.
יצירת דף סכין גילוח
הפעם WebGLGzip.cshtml
צור את הקובץ באמצעות אותו הליך כמו בעת לא דחוס.
הקוד הוא כדלקמן עם התייחסות פלט באחדות index.html
.
הנתיב תואם לתיקייה שיצרת webgl-gzip
קודם לכן עבור קובצי 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>
}
שנה כדי לאפשר ניווט בדף 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
מגדיר שכתוב Content-Encoding
br
כך שיתאים Content-Type
לסיומת הקובץ ללא .
עם זאת, הקובץ אינו נגיש כברירת מחדל ב- ASP.NET Core,.br
ולכן provider.Mappings
הוספתי אותו עם .br
.
לאחר מכן, הפעל את איתור הבאגים ובדוק אם המשחק פועל כראוי.
אם הגדרת אותו כראוי והמשחק עדיין לא מוצג, נסה לנקות את המטמון של דפדפן האינטרנט כדי לנקות את קבצי ה- Cookie שלך.
הפעלת WebGL דחוס עם Brotli
ההליך כמעט זהה ל- Gzip, החלפת חלק Gzip עם Brotli. עם זאת, קבצי Brotli ( .br) אינם נגישים כברירת מחדל ב- ASP.NET Core. עליך להגדיר אותו כך שתוכל לגשת אליו, אך אם אתה משתמש בקוד בזמן Gzip, הוא נתמך.
ראשית, צור פריסת קבצים ודף WebGL.
מיקום קובץ WebGL
wwwroot
webgl-brotli
תחת צור תיקיה, העתק את התיקיה , מקובץ WebGL שיצרת Build
TemplateData
באמצעות Brotli.
יצירת דף סכין גילוח
צור את הקובץ באמצעות WebGLBrotli.cshtml
אותם שלבים כמו עבור Gzip.
הקוד הוא כדלקמן עם התייחסות פלט באחדות index.html
.
הנתיב תואם לתיקייה שיצרת webgl-brotli
קודם לכן עבור קובצי 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>
}
שנה כדי לאפשר ניווט בדף 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 נתמך, תוכל להשתמש באותו קוד.
לאחר תיקונו, הפעל ניפוי באגים ובדוק אם המשחק עובד.
אם הגדרת אותו כראוי והמשחק עדיין לא מוצג, נסה לנקות את המטמון של דפדפן האינטרנט כדי לנקות את קבצי ה- Cookie שלך.
הבנת התסמינים של גישה לקבצי Brotli בשרת אינטרנט של IIS
Brotli אינו נתמך על-ידי IIS כברירת מחדל, ולכן נדרשת תצורה בצד IIS. נראה כי זה יכול להיות מטופל על ידי ביצוע הגדרות מתקדמות, אבל אני לא אסביר את זה בטיפ זה. אנא עיין במידע המקושר להלן.
- asp.net Core 2.2 brotli דחיסה לא עובד על IIS?
- מבט כולל על דחיסת IIS
- WebGL: דוגמת קוד תצורת שרת
- WebGL - פריסת גרסאות דחוסות
הודעת שגיאה
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)