Spuštění Unity WebGL s ASP.NET Core
Ověřovací prostředí
- Windows
-
- Systém Windows 11
- Editor jednoty
-
- 2020.3.25f1
- Visual Studio
-
- Visual Studio 2022
- ASP.NET jádro
-
- ASP.NET Core 6.0
- Internetová informační služba (IIS)
-
- Služba IIS 10.0
Nejprve
Naučte se, jak spustit herní výstup jako WebGL v Unity na webovém serveru se systémem ASP.NET Core. U herních programů použijte výstupy v níže uvedených tipech. Příklad hry používá 2D plošinovkovou mikrohru, kterou lze vytvořit z Unity Hubu.
Vysvětlím, jak nastavit "Uncompressed WebGL", "WebGL compressed with Gzip" a "WebGL compressed with Brotli" pro spouštění WebGL her. Postup je stejný pro všechny z nich.
Používáme Visual Studio 2022, ASP.NET Core 6,0, ale starší verze budou pravděpodobně fungovat. Struktura počátečního kódu je však pro každou verzi odlišná, proto prosím pochopte rozdíly sami.
Vytvoření základního projektu ASP.NET
Spusťte "Visual Studio 2022" z nabídky Start.
Vyberte vytvořit nový projekt.
Tentokrát vyberte jako ukázku "ASP.NET Core Web App". Pokud používáte ASP.NET Core, můžete spouštět jiné šablony, ale budete muset postupovat podle jednotlivých šablon, jak je sestavit.
Nastavte název a umístění projektu libovolně.
Další informace ponechte tak, jak jsou.
Projekt byl vytvořen.
Spuštění nekomprimovaného WebGL
Připravte program WebGL vytvořený bez komprese.
Ujistěte se, že hra funguje rychle
ASP.NET Zkuste spustit hru WebGL s menším počtem nastavení bez dodržení základní etikety.
V ASP.NET Core nemáte přístup k některým souborům WebGL vygenerovaným Unity ve výchozím stavu. Učiňte to přístupným.
Program.cs
Otevřete z projektu Program.cs
. Platí pro starší verze Startup.cs
ASP.NET Core.
Přidejte obor názvů do horní části kódu a nahraďte následující v kódu 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
, takže při přístupu .wasm
k souboru jej lze vrátit klientovi se zadaným Content-Type
souborem .
Nasazení WebGL
Do projektu wwwroot
umístěte následující složky souborů z Unity.
- index.html
- Vybudovat
- TemplateData
Index.cshtml
index.html
Otevřete odkaz, abyste k němu měli pří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>
Spusťte program a ujistěte se, že hra funguje.
Spuštění programu WebGL na stránce Razor
Předchozí hra běžela na statickém souboru HTML, takže běží na místě, které nemá nic společného s ASP.NET Core. Není to příliš žádoucí pro jednotnost programu, takže přesuneme chování souboru HTML na Razor Pages.
Klikněte pravým tlačítkem na složku Stránky v projektu a přidejte novou položku.
Vyberte Razor Page – empty. Není zadán žádný konkrétní název, ale je zde WebGL.cshtml
přidán.
Zobrazí se kód.
index.html
Viz obsah souboru a port do WebGL.cshtml
.
link
Existují některé podivné body, jako například jak umístit značku, ale nechám to tak, jak to je, kvůli jednoduchosti vysvětlení.
@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
Přidejte odkaz na soubor .
<!-- 省略 -->
<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>
Zkuste spustit program. Můžete vidět, že záhlaví a zápatí _Layout.cshtml
jsou zobrazeny na stránce WebGL podle .
Změna umístění souborů WebGL
Soubor WebGL jsem umístil přímo pod , ale tato metoda jej přepíše, když umístíte dva nebo více souborů WebGL wwwroot
.
Vysvětlím, jak to dát do samostatných složek a přesunout to.
Nejprve vytvořte novou složku s názvem "webgl" a přesuňte ji tam. Dvě složky, které mají být přesunuty, jsou , Build
TemplateData
.
index.html
Už jsem ji přenesl na Razor Pages a mohu ji bezpečně odstranit.
Vzhledem k tomu, že WebGL.cshtml
jsme prohloubili hierarchii složek, prohloubíme také cestu popsanou v . Korekce je 3 řádky.
Před opravou
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
var buildUrl = "Build";
Po opravě
<link rel="shortcut icon" href="webgl/TemplateData/favicon.ico">
<link rel="stylesheet" href="webgl/TemplateData/style.css">
var buildUrl = "webgl/Build";
Spusťte program a zjistěte, zda funguje správně.
Spuštění WebGL komprimovaného pomocí Gzip
Přípona souboru komprimovaného Gzip je .gz
, a je to soubor, který může zpracovat ASP.NET Core,
Unity WebGL Content-Type
a jsou zpracovány odlišně a vyžadují konverzi.
Nejprve vytvořte nasazení souboru WebGL a stránku.
Umístění souboru WebGL
wwwroot
webgl-gzip
Vytvořte složku pod Gzip a zkopírujte složku , ze souboru Build
TemplateData
WebGL, který jste vytvořili pomocí programu Gzip.
Vytvoření stránky Razor
Tentokrát WebGLGzip.cshtml
vytvořte soubor stejným postupem jako při dekomprimaci.
Kód je následující s odkazem na výstup v index.html
jednotce.
Cesta odpovídá složce, kterou jste vytvořili webgl-gzip
dříve pro soubory 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>
}
Upravit tak, aby umožňoval navigaci na Index.cshtml
tuto 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>
Fixační program.cs
app.UseStaticFiles
Upravte část, která zpracovává metodu následujícím způsobem.
Před opravou
// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider,
});
// ここまで追加
Po opravě
// ここから追加
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
vrátí soubor Content-Type
application/x-gzip
s .
Jak to je, Unity WebGL na klientovi to nemůže určit, takže .gz
to přepíšu a vracím podle Content-Type
přípony souboru, který vylučuje .
Content-Encoding
Také jsem to nastavil, protože je to gzip
nutné.
Mimochodem, také jsem dal dohromady kód Brocti, takže tento kód můžete použít tak, jak je v korespondenci Brotli další položky.
Brotli také .br
nastaví přepis Content-Encoding
br
tak, aby odpovídal Content-Type
příponě souboru bez .
Soubor je však ve výchozím nastavení v ASP.NET Core nepřístupný,.br
takže provider.Mappings
jsem ho přidal pomocí .br
.
Poté spusťte ladění a zkontrolujte, zda hra funguje správně.
Pokud jste ji nastavili správně a hra se stále nezobrazuje, zkuste vymazat mezipaměť webového prohlížeče a vymazat soubory cookie.
Spuštění WebGL komprimovaného pomocí Brotli
Postup je téměř stejný jako Gzip, nahrazení části Gzip Brotli. Soubory Brotli (.br) však nejsou ve výchozím nastavení v ASP.NET Core přístupné. Musíte jej nakonfigurovat tak, abyste k němu měli přístup, ale pokud používáte kód v době Gzip, je podporován.
Nejprve vytvořte nasazení souboru WebGL a stránku.
Umístění souboru WebGL
wwwroot
webgl-brotli
V části Vytvořit složku zkopírujte složku , ze souboru WebGL, který Build
TemplateData
jste vytvořili pomocí Brotli.
Vytvoření stránky Razor
Vytvořte soubor stejným WebGLBrotli.cshtml
postupem jako pro Gzip.
Kód je následující s odkazem na výstup v index.html
jednotce.
Cesta odpovídá složce, kterou jste vytvořili webgl-brotli
dříve pro soubory 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>
}
Upravit tak, aby umožňoval navigaci na Index.cshtml
tuto 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>
Fixační program.cs
Pokud jej upravíte, když je podporován Gzip, můžete použít stejný kód.
Po opravě spusťte ladění a zkontrolujte, zda hra funguje.
Pokud jste ji nastavili správně a hra se stále nezobrazuje, zkuste vymazat mezipaměť webového prohlížeče a vymazat soubory cookie.
Vysvětlení příznaků přístupu k souborům Brotli na webovém serveru služby IIS
Brotli není ve výchozím nastavení službou IIS podporován, takže je vyžadována konfigurace na straně služby IIS. Zdá se, že to lze zvládnout provedením pokročilých nastavení, ale v tomto tipu to nevysvětlím. Přečtěte si níže uvedené informace.
- asp.net komprese brotli core 2.2 nefunguje na IIS?
- Přehled komprese služby IIS
- WebGL: Ukázka konfiguračního kódu serveru
- WebGL – nasazení komprimovaných sestavení
zpráva o chybě
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)