Spustenie Unity WebGL s ASP.NET Core
Prostredie overovania
- Windows
-
- Windows 11
- Editor jednoty
-
- 2020.3.25f1
- Vizuálne štúdio
-
- Visual Studio 2022
- ASP.NET jadro
-
- ASP.NET Core 6.0
- Internetové informačné služby (IIS)
-
- IIS 10.0
Najskôr
Naučte sa, ako spustiť výstup hry ako WebGL v Unity na webovom serveri ASP.NET Core. V prípade herných programov použite tie, ktoré sú uvedené v krokoch tipov nižšie. Príklad hry používa 2D plošinovku Microgame, ktorú je možné vytvoriť z Unity Hub.
Vysvetlím, ako nastaviť "Uncompressed WebGL", "WebGL compressed with Gzip" a "WebGL compressed with Brotli" na spustenie hier WebGL. Postup je rovnaký pre všetky z nich.
Používame Visual Studio 2022, ASP.NET Core 6.0, ale staršie verzie pravdepodobne budú fungovať. Štruktúra počiatočného kódu je však pre každú verziu odlišná, preto rozdiely pochopte sami.
Vytvorenie ASP.NET základného projektu
Spustite "Visual Studio 2022" z ponuky Štart.
Vyberte položku Vytvoriť nový projekt.
Tentoraz vyberte ako ukážku možnosť "ASP.NET Core Web App". Ak používate ASP.NET Core, môžete spustiť iné šablóny, ale budete musieť postupovať podľa jednotlivých šablón, ako ju vytvoriť.
Ľubovoľne nastavte názov a umiestnenie projektu.
Ďalšie informácie nechajte tak, ako sú.
Projekt bol vytvorený.
Spustenie nekomprimovaného rozhrania WebGL
Pripravte program WebGL vytvorený bez kompresie.
Uistite sa, že hra funguje rýchlo
ASP.NET Skúste spustiť hru WebGL s menším počtom nastavení bez dodržiavania základnej etikety.
V ASP.NET Core nemôžete získať prístup k niektorým súborom WebGL vysielaným Unity v predvolenom stave. Urobte to prístupným.
Program.cs
Otvoriť z Program.cs
projektu. Platí pre staršie verzie Startup.cs
ASP.NET Core.
Pridajte priestor názvov do hornej časti kódu a v kóde app.UseStaticFiles();
nahraďte nasledovné:
// ここから追加
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
, takže keď je súbor prístupný, .wasm
môže byť vrátený klientovi so zadaným Content-Type
.
Nasadenie WebGL
Umiestnite do projektu wwwroot
nasledujúce priečinky súborov z Unity .
- index.html
- Budovať
- TemplateData
Index.cshtml
index.html
Otvorte prepojenie, aby ste k nemu mali prístup.
<!-- 省略 -->
<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>
Spustite program a uistite sa, že hra funguje.
Spustenie programu WebGL na stránke Razor
Predchádzajúca hra bežala na statickom HTML súbore, takže beží na mieste, ktoré nemá nič spoločné s ASP.NET Core. Nie je to veľmi žiaduce pre jednotnosť programu, takže presunieme správanie súboru HTML na Razor Pages.
Kliknite pravým tlačidlom myši na priečinok Pages v projekte a pridajte novú položku.
Vyberte položku Razor Page - Empty. Nie je špecifikovaný žiadny konkrétny názov, ale je tu WebGL.cshtml
pridaný .
Zobrazí sa kód.
index.html
Pozrite si obsah súboru a port na WebGL.cshtml
.
link
Existuje niekoľko zvláštnych bodov, napríklad ako umiestniť značku, ale kvôli jednoduchosti vysvetlenia to nechám tak, ako to je.
@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
Pridajte prepojenie na .
<!-- 省略 -->
<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>
Pokúste sa spustiť program. Môžete vidieť, že hlavička a päta _Layout.cshtml
sú zobrazené na stránke WebGL podľa .
Zmena umiestnenia súborov WebGL
Súbor WebGL som umiestnil priamo pod , ale táto metóda ho prepíše, keď umiestnite dva alebo viac súborov WebGL wwwroot
.
Vysvetlím, ako to dať do samostatných priečinkov a presunúť.
Najprv vytvorte nový priečinok s názvom "webgl" a presuňte ho tam. Dva priečinky, ktoré sa majú Build
presunúť, sú , TemplateData
.
index.html
Už som ho preniesol na Razor Pages a môžem ho bezpečne odstrániť.
Keďže WebGL.cshtml
sme prehĺbili hierarchiu priečinkov, prehĺbime aj cestu opísanú v . Korekcia je 3 riadky.
Pred korekciou
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
var buildUrl = "Build";
Po korekcii
<link rel="shortcut icon" href="webgl/TemplateData/favicon.ico">
<link rel="stylesheet" href="webgl/TemplateData/style.css">
var buildUrl = "webgl/Build";
Spustite program a zistite, či funguje správne.
Spustenie rozhrania WebGL komprimovaného pomocou Gzip
Prípona súboru komprimovaného Gzip je .gz
, a je to súbor, ktorý môže spracovať ASP.NET Core,
Unity WebGL Content-Type
a sú spracované inak a vyžadujú konverziu.
Najprv vytvorte nasadenie súboru WebGL a stránku.
Umiestnenie súboru WebGL
wwwroot
webgl-gzip
Vytvorte priečinok pod Gzip a skopírujte priečinok , zo súboru Build
TemplateData
WebGL, ktorý ste vytvorili pomocou Gzip.
Vytvorenie stránky s holiacim strojčekom
Tentoraz WebGLGzip.cshtml
vytvorte súbor rovnakým postupom ako pri nekomprimovaní.
Kód je nasledovný s odkazom na výstup v index.html
jednote.
Cesta sa zhoduje s priečinkom, ktorý ste predtým vytvorili webgl-gzip
pre súbory 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>
}
Upraviť, ak chcete povoliť navigáciu na Index.cshtml
túto stránku.
<!-- 省略 -->
<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>
Opravný program.cs
app.UseStaticFiles
Upravte časť, ktorá spracováva metódu, nasledovne.
Pred korekciou
// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider,
});
// ここまで追加
Po korekcii
// ここから追加
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");
}
}
},
});
// ここまで追加
V ASP.NET Core .gz
sa súbor Content-Type
application/x-gzip
vráti s .
Ako to je, Unity WebGL na klientovi to nemôže určiť, takže .gz
ho prepíšem a vrátim podľa Content-Type
prípony súboru, ktorá vylučuje .
Content-Encoding
Nastavil som to aj preto, že je to gzip
potrebné.
Mimochodom, dal som dohromady aj kód Brotli, takže tento kód môžete použiť tak, ako je to v korešpondencii Brotli ďalšej položky.
Brotli tiež .br
nastaví prepísanie Content-Encoding
br
tak, aby zodpovedalo Content-Type
prípone súboru bez .
Súbor je však predvolene neprístupný v ASP.NET Core,.br
takže provider.Mappings
som ho pridal pomocou .br
.
Potom spustite ladenie a skontrolujte, či hra funguje správne.
Ak ste hru nastavili správne a hra sa stále nezobrazuje, skúste vymazať súbory cookie z vyrovnávacej pamäte webového prehliadača.
Spustenie WebGL komprimovaného pomocou Brotli
Postup je takmer rovnaký ako postup Gzip, pričom časť Gzip sa nahrádza Brotli. Súbory Brotli (.br) však nie sú predvolene prístupné v ASP.NET Core. Musíte ho nakonfigurovať tak, aby ste k nemu mali prístup, ale ak používate kód v čase Gzip, je podporovaný.
Najprv vytvorte nasadenie súboru WebGL a stránku.
Umiestnenie súboru WebGL
wwwroot
webgl-brotli
V časti Vytvoriť priečinok skopírujte priečinok , zo súboru WebGL, ktorý Build
TemplateData
ste vytvorili pomocou Brotli.
Vytvorenie stránky s holiacim strojčekom
Vytvorte súbor pomocou WebGLBrotli.cshtml
rovnakých krokov ako pre Gzip.
Kód je nasledovný s odkazom na výstup v index.html
jednote.
Cesta sa zhoduje s priečinkom, ktorý ste predtým vytvorili webgl-brotli
pre súbory 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>
}
Upraviť, ak chcete povoliť navigáciu na Index.cshtml
túto stránku.
<!-- 省略 -->
<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>
Opravný program.cs
Ak ho upravíte, keď je podporovaný Gzip, môžete použiť rovnaký kód.
Po oprave spustite ladenie a skontrolujte, či hra funguje.
Ak ste hru nastavili správne a hra sa stále nezobrazuje, skúste vymazať súbory cookie z vyrovnávacej pamäte webového prehliadača.
Pochopenie príznakov prístupu k súborom Brotli na webovom serveri služby IIS
Brotli nie je štandardne podporovaný IIS, takže je potrebná konfigurácia na strane IIS. Zdá sa, že sa to dá zvládnuť vykonaním pokročilých nastavení, ale v tomto tipe to nebudem vysvetľovať. Pozrite si informácie uvedené nižšie.
- asp.net kompresia jadra 2.2 brotli nefunguje na IIS?
- Prehľad kompresie služby IIS
- WebGL: Ukážka konfiguračného kódu servera
- WebGL - Nasadenie komprimovaných zostáv
Chybové hlásenie
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)