Running Unity WebGL s ASP.NET jedrom
Okolje za preverjanje
- Windows
-
- Windows 11
- Urejevalnik Unity
-
- 2020.3.25F1
- Visual Studio
-
- Visual Studio 2022
- ASP.NET jedro
-
- ASP.NET Core 6.0
- Internetne informacijske storitve (IIS)
-
- Storitve IIS 10.0
Sprva
Naučite se zagnati izhod igre kot WebGL v aplikaciji Unity v spletnem strežniku, ki se izvaja ASP.NET Core. Za programe iger uporabite tiste, ki so na voljo v spodnjih korakih z nasveti. Primer igre uporablja 2D Platformer Microgame, ki ga lahko ustvarite iz središča Unity.
Razložil bom, kako nastaviti "Nestisnjen WebGL", "WebGL stisnjen z Gzipom" in "WebGL stisnjen z Brotlijem" za zagon iger WebGL. Postopek je enak za vse.
Uporabljamo Visual Studio 2022, ASP.NET Core 6.0, vendar bodo starejše različice verjetno delovale. Vendar pa je struktura začetne kode za vsako različico drugačna, zato prosimo, da razlike razumete sami.
Ustvarjanje osrednjega projekta ASP.NET
Zaženite "Visual Studio 2022" iz začetnega menija.
Izberite Ustvari nov projekt.
Tokrat za vzorec izberite »ASP.NET Core Web App«. Če se izvajate ASP.NET jedru, lahko zaženete druge predloge, vendar boste morali vsaki predlogi slediti, kako jo ustvariti.
Poljubno nastavite ime in lokacijo projekta.
Dodatne informacije pustite takšne, kot so.
Projekt je nastal.
Zaženite nestisnjen WebGL
Pripravite program WebGL, ustvarjen brez stiskanja.
Prepričajte se, da igra deluje hitro
ASP.NET Poskusite zagnati igro WebGL z manj nastavitvami, ne da bi sledili osnovnemu bontonu.
V ASP.NET jedru ne morete dostopati do nekaterih datotek WebGL, ki jih oddaja Unity v privzetem stanju. Poskrbite, da bo to dostopno.
Program.cs
Odprite projekt Program.cs
. Velja za starejše različice Startup.cs
ASP.NET Core .
Dodajte imenski prostor na vrh kode in v kodi app.UseStaticFiles();
zamenjajte naslednje:
// ここから追加
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
, tako da se lahko ob dostopu do .wasm
datoteke vrne odjemalcu z določeno Content-Type
.
Uvajanje WebGL
V projekt wwwroot
vstavite te datotečne mape iz Unity .
- indeks.html
- Graditi
- Podatki predloge
Index.cshtml
index.html
Odprite povezavo, da boste lahko dostopali do nje.
<!-- 省略 -->
<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>
Zaženite program in se prepričajte, da igra deluje.
Zaženite program WebGL na strani Razor
Prejšnja igra je delovala na statični datoteki HTML, zato deluje na mestu, ki nima nič skupnega s ASP.NET jedrom. To ni zelo zaželeno za enotnost programa, zato bomo vedenje datoteke HTML premaknili na strani Razor.
Z desno tipko miške kliknite mapo Strani v projektu, da dodate nov element.
Izberite Stran z britvico - prazno. Ni določenega posebnega imena, vendar je dodano tukaj WebGL.cshtml
.
Koda je prikazana.
index.html
Oglejte si vsebino datoteke in vrata na WebGL.cshtml
.
link
Obstaja nekaj čudnih točk, na primer, kako postaviti oznako, vendar jo bom pustil takšno, kot je zaradi preprostosti razlage.
@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
Dodajte povezavo do .
<!-- 省略 -->
<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>
Poskusite zagnati program. Vidite lahko, da sta glava in noga _Layout.cshtml
prikazani na strani WebGL glede na .
Spreminjanje lokacije datotek WebGL
Datoteko WebGL sem postavil neposredno pod , vendar jo bo ta metoda prepisala, ko postavite dve ali več datotek WebGL wwwroot
.
Razložil bom, kako to postaviti v ločene mape in ga premakniti.
Najprej ustvarite novo mapo z imenom "webgl" in jo premaknite tja. Dve mapi, ki ju je treba premakniti, sta, Build
. TemplateData
index.html
Prenesel sem ga že na strani Razor in ga lahko varno izbrišem.
Ker WebGL.cshtml
smo poglobili hierarhijo map, bomo poglobili tudi pot, opisano v . Popravek je 3 vrstice.
Pred korekcijo
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
var buildUrl = "Build";
Po korekciji
<link rel="shortcut icon" href="webgl/TemplateData/favicon.ico">
<link rel="stylesheet" href="webgl/TemplateData/style.css">
var buildUrl = "webgl/Build";
Zaženite program in preverite, ali deluje pravilno.
Izvajanje WebGL, stisnjeno z Gzipom
Razširitev datoteke, stisnjene z Gzipom, je , in to je .gz
datoteka, ki jo lahko obravnava ASP.NET jedro,
Unity WebGL Content-Type
in se obravnavajo drugače in zahtevajo pretvorbo.
Najprej ustvarite uvajanje datotek WebGL in stran.
Postavitev datoteke WebGL
wwwroot
webgl-gzip
Ustvarite mapo v razdelku Gzip in kopirajte mapo , iz datoteke Build
TemplateData
WebGL, ki ste jo ustvarili z Gzipom.
Ustvarjanje strani z britvico
Tokrat WebGLGzip.cshtml
ustvarite datoteko po enakem postopku kot pri nestisnjenju.
Koda je naslednja glede na izhod v index.html
enotnosti.
Pot se ujema z mapo, ki ste jo prej ustvarili webgl-gzip
za datoteke 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>
}
Spremeni, da omogočite krmarjenje do Index.cshtml
te strani.
<!-- 省略 -->
<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>
Program določanja.cs
app.UseStaticFiles
Del, ki obdeluje metodo, spremenite na naslednji način.
Pred korekcijo
// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider,
});
// ここまで追加
Po korekciji
// ここから追加
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
se datoteka Content-Type
application/x-gzip
vrne z .
Kot je, Unity WebGL na odjemalcu ga ne more določiti, zato .gz
ga ponovno napišem in vrnem glede Content-Type
na razširitev datoteke, ki izključuje .
Content-Encoding
Postavil sem ga tudi zato, ker je gzip
to potrebno.
Mimogrede, tudi Brottijevo kodo sem sestavil, tako da lahko to kodo uporabite tako, kot je v Brotlijevi korespondenci naslednjega elementa.
Brotli nastavi tudi .br
prepisovanje Content-Encoding
br
, da se ujema s Content-Type
pripono datoteke brez .
Vendar pa je datoteka privzeto nedostopna v ASP.NET jedru,.br
zato provider.Mappings
sem jo dodal z .br
.
Po tem zaženite odpravljanje napak in preverite, ali igra deluje pravilno.
Če ste ga pravilno nastavili in se igra še vedno ne prikaže, poskusite počistiti predpomnilnik spletnega brskalnika, da izbrišete piškotke.
Zagon WebGL, stisnjen z Brotli
Postopek je skoraj enak kot Gzip, ki nadomešča del Gzip z Brotlijem. Vendar pa datoteke Brotli (.br) privzeto niso dostopne v ASP.NET jedru. Konfigurirati ga morate tako, da lahko dostopate do njega, če pa kodo uporabljate v času Gzipa, je podprta.
Najprej ustvarite uvajanje datotek WebGL in stran.
Postavitev datoteke WebGL
wwwroot
webgl-brotli
V razdelku Ustvari mapo kopirajte mapo , iz Build
TemplateData
datoteke WebGL, ki ste jo ustvarili z Brotlijem.
Ustvarjanje strani z britvico
Ustvarite datoteko z WebGLBrotli.cshtml
enakimi koraki kot za Gzip.
Koda je naslednja glede na izhod v index.html
enotnosti.
Pot se ujema z mapo, ki ste jo prej ustvarili webgl-brotli
za datoteke 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>
}
Spremeni, da omogočite krmarjenje do Index.cshtml
te strani.
<!-- 省略 -->
<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>
Program določanja.cs
Če jo spremenite, ko je Gzip podprt, lahko uporabite isto kodo.
Ko ga popravite, zaženite odpravljanje napak in preverite, ali igra deluje.
Če ste ga pravilno nastavili in se igra še vedno ne prikaže, poskusite počistiti predpomnilnik spletnega brskalnika, da izbrišete piškotke.
Razumevanje simptomov dostopa do datotek Brotli v spletnem strežniku storitev IIS
Storitve IIS privzeto ne podpirajo storitve Brotli, zato je potrebna konfiguracija na strani storitev IIS. Zdi se, da ga je mogoče obravnavati z naprednimi nastavitvami, vendar tega v tem nasvetu ne bom razložil. Oglejte si spodnje informacije.
- asp.net stiskanje jedra 2.2 brotli ne deluje v storitvah IIS?
- Pregled stiskanja storitev IIS
- WebGL: Vzorec konfiguracijske kode strežnika
- WebGL - Uvajanje stisnjenih gradenj
Sporočilo o napaki
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)