Unity WebGL-i käivitamine ASP.NET Core'iga

Lehekülg uuendatud :
Lehe loomise kuupäev :

Kontrollimise keskkond

Windows
  • Windows 11
Ühtsuse toimetaja
  • 2020.3.25f1
Visuaalne stuudio
  • Visual Studio 2022
ASP.NET Tuum
  • ASP.NET Tuum 6.0
Interneti-teabeteenused (IIS)
  • IIS 10.0

Alguses

Siit saate teada, kuidas käivitada mängu väljundit WebGL-ina Unitys veebiserveris ASP.NET kus töötab Core. Mänguprogrammide puhul kasutage allolevates näpunäidetes väljundeid. Mängu näites kasutatakse 2D Platformer Microgame'i, mida saab luua Unity Hubist.

Selgitan, kuidas seadistada WebGL-mängude käitamiseks "Tihendamata WebGL", "Gzipiga tihendatud WebGL" ja "Brotliga tihendatud WebGL". Menetlus on nende kõigi jaoks sama.

Kasutame Visual Studio 2022, ASP.NET Core 6.0, kuid vanemad versioonid tõenäoliselt töötavad. Kuid esialgse koodi struktuur on iga versiooni puhul erinev, nii et palun mõistke erinevusi ise.

ASP.NET põhiprojekti loomine

Käivitage menüüst Start "Visual Studio 2022".

Valige Loo uus projekt.

Seekord valige näidiseks "ASP.NET Core Web App". Kui kasutate ASP.NET Core'i, saate käivitada ka teisi malle, kuid peate järgima iga malli, kuidas seda koostada.

Määrake projekti nimi ja asukoht suvaliselt.

Jätke lisateave nii, nagu see on.

Projekt on loodud.

Käivitage tihendamata WebGL

Valmistage ette WebGL-programm, mis on loodud ilma tihendamiseta.

Veenduge, et mäng töötab kiiresti

ASP.NET Proovige käivitada WebGL-mäng vähemate sätetega, järgimata põhietiketti.

ASP.NET Core'is ei pääse te juurde mõnele Unity poolt vaikeolekus edastatud WebGL-failile. Tehke see kättesaadavaks.

Kava.cs

Avage oma Program.cs projektist. Kehtib varasemate ASP.NET Core versioonide Startup.cs kohta .

Lisage koodi ülaossa nimeruum ja asendage koodis app.UseStaticFiles(); järgmine:

// ここから追加
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, nii et failile juurdepääsul .wasm saab selle kliendile tagastada määratud Content-Type .

WebGL-i juurutamine

Paigutage oma projekti wwwroot järgmised failikaustad Unityst .

  • sisukord.html
  • Ehitama
  • Malli andmed

Index.cshtmlindex.html Avage link, et saaksite sellele juurde pääseda.

<!-- 省略 -->

<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>

Käivitage programm ja veenduge, et mäng töötab.

Käivitage WebGL-programm habemenuga lehel

Eelmine mäng jooksis staatilise HTML-failiga, nii et see töötab kohas, millel pole midagi pistmist ASP.NET Core'iga. Programmi ühtsuse huvides pole see eriti soovitav, seega teisaldame HTML-faili käitumise Razor Pages'ile.

Uue üksuse lisamiseks paremklõpsake projekti kausta Leheküljed.

Valige Razor Page - Tühi. Konkreetset nime pole täpsustatud, kuid see lisatakse siia WebGL.cshtml .

Kuvatakse kood.

index.html Vaadake faili sisu ja porti . WebGL.cshtml link On mõned kummalised punktid, näiteks kuidas silti paigutada, kuid ma jätan selle selgituse lihtsuse huvides nii, nagu see on.

@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.cshtmlWebGL Lingi lisamine saidile .

<!-- 省略 -->

<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>

Proovige programmi käivitada. Näete, et päis ja jalus _Layout.cshtml kuvatakse WebGL-i lehel vastavalt .

WebGL-failide asukoha muutmine

Panin WebGL-faili otse alla , kuid see meetod kirjutab selle üle, kui asetate kaks või enam WebGL-faili wwwroot . Ma selgitan, kuidas seda eraldi kaustadesse panna ja teisaldada.

Kõigepealt looge uus kaust nimega "webgl" ja liigutage see sinna. Kaks teisaldatavat kausta Buildon , TemplateData . index.html Olen selle juba Razor Pages'i teisaldanud ja saan selle turvaliselt kustutada.

Kuna WebGL.cshtml oleme süvendanud kaustahierarhiat, süvendame ka jaotises . Parandus on 3 rida.

Enne korrigeerimist

<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
    var buildUrl = "Build";

Pärast korrigeerimist

<link rel="shortcut icon" href="webgl/TemplateData/favicon.ico">
<link rel="stylesheet" href="webgl/TemplateData/style.css">
    var buildUrl = "webgl/Build";

Käivitage programm, et näha, kas see töötab korralikult.

Gzipiga tihendatud WebGL-i käivitamine

Gzipi poolt tihendatud faili laiendus on , ja see on .gz fail, mida saab käsitleda ASP.NET Core, Unity WebGL Content-Type ja neid käsitletakse erinevalt ja need vajavad teisendamist.

Esmalt looge WebGL-faili juurutamine ja leht.

WebGL-failide paigutus

wwwrootwebgl-gzip Looge Gzipi all kaust ja kopeerige kaust , WebGL-failistBuildTemplateData, mille lõite Gzipiga.

Raseerija lehe loomine

Seekord WebGLGzip.cshtml looge fail sama protseduuri abil nagu tihendamata.

Kood on järgmine, viidates väljundile ühtsuses index.html . Tee ühtib varem WebGL-failide jaoks loodud webgl-gzip kaustaga.

@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>
}

Muuda, et lubada sellele lehele navigeerimine 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>

Fikseerimise programm.cs

app.UseStaticFiles Muutke meetodit töötlevat osa järgmiselt.

Enne korrigeerimist

// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";

app.UseStaticFiles(new StaticFileOptions()
{
  ContentTypeProvider = provider,
});
// ここまで追加

Pärast korrigeerimist

// ここから追加
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'is .gz tagastab fail Content-Type application/x-gzip . Nagu see on, ei saa Unity WebGL kliendil seda kindlaks teha, nii et .gz ma kirjutan ümber ja tagastan selle Content-Type vastavalt faili laiendusele, mis välistab . Content-Encoding Ma seadsin selle ka sellepärast, et see gzip on vajalik.

Muide, panin ka Brotli koodi kokku, nii et saate seda koodi kasutada nii, nagu see on järgmise üksuse Brotli kirjavahetuses. Brotli määrab ka .br ümberkirjutamise, et see Content-Encoding br vastaks Content-Type faili laiendusele ilma . Kuid fail pole ASP.NET Core'is vaikimisi juurdepääsetav,.br nii et provider.Mappings lisasin selle koos .br .

Seejärel käivitage silumine ja kontrollige, kas mäng töötab õigesti.

Kui olete selle õigesti seadistanud ja mängu ikka ei kuvata, proovige küpsiste kustutamiseks tühjendada veebibrauseri vahemälu.

Brotliga tihendatud WebGL-i käivitamine

Protseduur on peaaegu sama, mis Gzip, asendades Gzipi osa Brotliga. Kuid Brotli (.br) failid pole ASP.NET Core'is vaikimisi juurdepääsetavad. Peate selle konfigureerima nii, et saaksite sellele juurde pääseda, kuid kui kasutate koodi Gzipi ajal, toetatakse seda.

Esmalt looge WebGL-faili juurutamine ja leht.

WebGL-failide paigutus

wwwrootwebgl-brotli Kopeerige jaotises Kausta loomine kaust , mis pärineb Brotliga loodud WebGL-failistBuildTemplateData.

Raseerija lehe loomine

Looge fail samade sammudega WebGLBrotli.cshtml nagu Gzipi puhul.

Kood on järgmine, viidates väljundile ühtsuses index.html . Tee ühtib varem WebGL-failide jaoks loodud webgl-brotli kaustaga.

@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>
}

Muuda, et lubada sellele lehele navigeerimine 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>

Fikseerimise programm.cs

Kui muudate seda, kui Gzip on toetatud, saate kasutada sama koodi.

Pärast selle kinnitamist käivitage silumine ja kontrollige, kas mäng töötab.

Kui olete selle õigesti seadistanud ja mängu ikka ei kuvata, proovige küpsiste kustutamiseks tühjendada veebibrauseri vahemälu.

IIS-i veebiserveris Brotli failidele juurdepääsu sümptomite mõistmine

IIS ei toeta vaikimisi Brotlit, seega on IIS-i poolel konfigureerimine vajalik. Tundub, et seda saab käsitseda täpsemate seadete abil, kuid ma ei selgita seda selles nõuandes. Palun vaadake allpool lingitud teavet.

veateade

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)