A Unity WebGL futtatása ASP.NET Core-ral
Ellenőrzési környezet
- Windows
-
- Windows 11 esetén
- Unity-szerkesztő
-
- 2020.3.25f1
- Visual Studio
-
- Visual Studio 2022
- ASP.NET mag
-
- ASP.NET Core 6.0
- Internet Information Services (IIS)
-
- IIS 10.0
Először
Ismerje meg, hogyan futtathat egy játék kimenetét WebGL-ként a Unityben egy ASP.NET Core-t futtató webkiszolgálón. Játékprogramok esetén használja az alábbi tippek lépéseit. A játékpélda a 2D Platformer Microgame-t használja, amely a Unity Hubból hozható létre.
Elmagyarázom, hogyan kell beállítani a "Tömörítetlen WebGL", a "WebGL tömörítve Gzip" és a "WebGL tömörítve Brotlival" a WebGL játékok futtatásához. Az eljárás mindegyiknél azonos.
A Visual Studio 2022-t ASP.NET Core 6.0-t használjuk, de a régebbi verziók valószínűleg működni fognak. A kezdeti kód szerkezete azonban minden verziónál eltérő, ezért kérjük, értse meg a különbségeket.
ASP.NET alapprojekt létrehozása
Indítsa el a "Visual Studio 2022" alkalmazást a Start menüből.
Válassza az Új projekt létrehozása lehetőséget.
Ezúttal válassza ki a "ASP.NET Core Web App" lehetőséget mintaként. Ha ASP.NET Core-on fut, futtathat más sablonokat is, de az egyes sablonokat követnie kell a létrehozásukhoz.
Tetszőlegesen állítsa be a projekt nevét és helyét.
Hagyja változatlanul a további információkat.
A projekt létrejött.
Tömörítetlen WebGL futtatása
Készítsen elő tömörítés nélkül létrehozott WebGL-programot.
Győződjön meg arról, hogy a játék gyorsan működik
ASP.NET Próbáljon meg kevesebb beállítással futtatni egy WebGL-játékot az alapvető etikett betartása nélkül.
A ASP.NET Core-ban nem férhet hozzá egyes, a Unity által kibocsátott WebGL-fájlokhoz az alapértelmezett állapotban. Tegye ezt hozzáférhetővé.
Program.cs
Nyissa meg a Program.cs
projektből. A korábbi ASP.NET Core verziókra Startup.cs
vonatkozik.
Adjon hozzá egy névteret a kód elejéhez, és cserélje le a következőt a kódban 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
, így egy fájl elérésekor .wasm
azt a megadott Content-Type
.
WebGL telepítés
Helyezze a következő fájlmappákat a Unityből a projektbe wwwroot
.
- tárgymutató.html
- Épít
- Sablonadatok
Index.cshtml
index.html
Nyissa meg a hivatkozást, hogy hozzáférhessen.
<!-- 省略 -->
<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>
Futtassa a programot, és ellenőrizze, hogy a játék működik-e.
WebGL program futtatása borotvaoldalon
Az előző játék statikus HTML fájlon futott, tehát olyan helyen fut, amelynek semmi köze a ASP.NET Core-hoz. Ez nem túl kívánatos a program egységessége szempontjából, ezért a HTML fájl viselkedését áthelyezzük a Razor Pages oldalra.
Új elem hozzáadásához kattintson a jobb gombbal a projekt Pages mappájára.
Válassza a Razor Page - Empty lehetőséget. Nincs megadva konkrét név, de itt WebGL.cshtml
hozzáadódik .
Megjelenik a kód.
index.html
Tekintse meg a fájl tartalmát és a portot a . WebGL.cshtml
link
Van néhány furcsa pont, például a címke elhelyezése, de a magyarázat egyszerűsége érdekében hagyom úgy, ahogy van.
@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
Hivatkozás hozzáadása a következőhöz: .
<!-- 省略 -->
<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>
Próbálja meg futtatni a programot. Láthatja, hogy a fejléc és a lábléc _Layout.cshtml
a WebGL oldalon a szerint jelenik meg.
WebGL-fájlok helyének módosítása
A WebGL fájlt közvetlenül a alá helyeztem, de ez a módszer felülírja azt, ha két vagy több WebGL wwwroot
fájlt helyez el.
Elmagyarázom, hogyan lehet ezt külön mappákba helyezni és áthelyezni.
Először hozzon létre egy új, "webgl" nevű mappát, és helyezze át oda. A két áthelyezendő Build
mappa a következő TemplateData
: , .
index.html
Már átírtam a Razor Pages-re, és biztonságosan törölhetem.
Mivel WebGL.cshtml
elmélyítettük a mappahierarchiát, a mappában leírt elérési utat is mélyíteni fogjuk. A korrekció 3 sor.
Javítás előtt
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
var buildUrl = "Build";
Javítás után
<link rel="shortcut icon" href="webgl/TemplateData/favicon.ico">
<link rel="stylesheet" href="webgl/TemplateData/style.css">
var buildUrl = "webgl/Build";
Futtassa a programot, hogy ellenőrizze, megfelelően működik-e.
A Gzip tömörítéssel tömörített WebGL futtatása
A Gzip .gz
által tömörített fájl kiterjesztése , és ez egy olyan fájl, amelyet a ASP.NET Core kezelhet,
Unity WebGL Content-Type
és másképp kezelik, és átalakítást igényelnek.
Először hozzon létre egy WebGL-fájltelepítést és -oldalt.
WebGL fájl elhelyezése
wwwroot
webgl-gzip
Hozzon létre egy mappát a Gzip alatt, és másolja a , mappát a Gzip segítségével létrehozott WebGL fájlbólBuild
TemplateData
.
Borotvaoldal létrehozása
Ezúttal WebGLGzip.cshtml
hozza létre a fájlt ugyanazzal az eljárással, mint tömörítetlenül.
A kód a következő, hivatkozással a Unity kimenetére index.html
.
Az elérési út megegyezik a WebGL-fájlokhoz korábban létrehozott webgl-gzip
mappával.
@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>
}
Módosítsa az oldalra való navigáció Index.cshtml
engedélyezéséhez.
<!-- 省略 -->
<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>
Rögzítési program.cs
app.UseStaticFiles
Módosítsa a módszert feldolgozó részt az alábbiak szerint.
Javítás előtt
// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider,
});
// ここまで追加
Javítás után
// ここから追加
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");
}
}
},
});
// ここまで追加
A ASP.NET Core-ban .gz
a fájl Content-Type
application/x-gzip
a következővel tér vissza: .
Ahogy van, a kliens Unity WebGL nem tudja meghatározni, ezért .gz
átírom és visszaadom a fájl kiterjesztésének megfelelően Content-Type
, amely kizárja .
Content-Encoding
Azt is beállítom, gzip
mert szükséges.
Egyébként a Brotli kódot is összeraktam, így ezt a kódot úgy használhatja, mint a következő elem Brotli levelezésében.
A Brotli az újraírást br
Content-Encoding
is .br
beállítja, hogy megfeleljen Content-Type
a fájl kiterjesztésének .
A fájl azonban alapértelmezés szerint nem érhető el a ASP.NET Core-ban,.br
ezért provider.Mappings
hozzáadtam a -hez .br
.
Ezután futtassa a hibakeresést, és ellenőrizze, hogy a játék megfelelően működik-e.
Ha helyesen állította be, és a játék továbbra sem jelenik meg, próbálja meg törölni a böngésző gyorsítótárát a cookie-k törléséhez.
WebGL futtatása Brotli-val tömörítve
Az eljárás majdnem ugyanaz, mint a Gzip, a Gzip részt Brotli-val helyettesítve. A Brotli (.br) fájlok azonban alapértelmezés szerint nem érhetők el a ASP.NET Core-ban. Konfigurálnia kell, hogy hozzáférhessen, de ha a kódot a Gzip idején használja, akkor támogatott.
Először hozzon létre egy WebGL-fájltelepítést és -oldalt.
WebGL fájl elhelyezése
wwwroot
webgl-brotli
A Mappa létrehozása területen másolja a , mappát a Build
TemplateData
Brotlival létrehozott WebGL-fájlból.
Borotvaoldal létrehozása
Hozza létre a fájlt ugyanazokkal a lépésekkel WebGLBrotli.cshtml
, mint a Gzip esetében.
A kód a következő, hivatkozással a Unity kimenetére index.html
.
Az elérési út megegyezik a WebGL-fájlokhoz korábban létrehozott webgl-brotli
mappával.
@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>
}
Módosítsa az oldalra való navigáció Index.cshtml
engedélyezéséhez.
<!-- 省略 -->
<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>
Rögzítési program.cs
Ha módosítja, amikor a Gzip támogatott, használhatja ugyanazt a kódot.
A javítás után futtassa a hibakeresést, és ellenőrizze, hogy működik-e a játék.
Ha helyesen állította be, és a játék továbbra sem jelenik meg, próbálja meg törölni a böngésző gyorsítótárát a cookie-k törléséhez.
A Brotli-fájlok IIS-webkiszolgálón való elérésének következményeinek ismertetése
Az IIS alapértelmezés szerint nem támogatja a Brotlit, ezért az IIS oldalán konfiguráció szükséges. Úgy tűnik, hogy speciális beállításokkal kezelhető, de ebben a tippben nem magyarázom el. Kérjük, olvassa el az alább hivatkozott információkat.
- asp.net core 2.2 brotli tömörítés nem működik az IIS-en?
- IIS-tömörítés – áttekintés
- WebGL: Minta kiszolgálókonfigurációs kódra
- WebGL – Tömörített buildek üzembe helyezése
Hibaüzenet
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)