Oktatóanyag: Interfészek és egyéni modellek
Eben az oktatóanyagban az alábbiakkal fog megismerkedni:
- Mixed Reality-eszközkészlet hozzáadása a projekthez
- Modellállapot kezelése
- Az Azure Blob Storage konfigurálása modellbetöltéshez
- Modellek feltöltése és feldolgozása rendereléshez
Előfeltételek
- Ez az oktatóanyag az Oktatóanyag: Távolról renderelt modell megtekintése című oktatóanyagra épül.
Ismerkedés a Mixed Reality eszközkészlettel (MRTK)
A Mixed Reality Eszközkészlet (MRTK) egy platformfüggetlen eszközkészlet a vegyes valósági élmények létrehozásához. Az MRTK 2.8.3-at használjuk az interakciós és vizualizációs funkciókhoz.
Az MRTK importálásának hivatalos útmutatója tartalmaz néhány lépést, amelyeket nem kell tennünk. Csak ez a három lépés szükséges:
- A "Mixed Reality Toolkit/Mixed Reality Toolkit Foundation" 2.8.3-es verziójának importálása a projektbe a Mixed Reality funkcióeszközön keresztül (MRTK importálása).
- Futtassa az MRTK konfigurációs varázslóját (AZ MRTK konfigurálása).
- Adja hozzá az MRTK-t az aktuális jelenethez (Hozzáadás a jelenethez). Az oktatóanyagban javasolt profil helyett használja itt az ARRMixedRealityToolkitConfigurationProfile parancsot.
Az oktatóanyag által használt objektumok importálása
Ebben a fejezetben egy alapszintű modellnézet-vezérlő mintát implementálunk a tárgyalt anyagok nagy részének esetében. A minta modell része az Azure Remote Rendering-specifikus kód és az Azure Remote Renderinghez kapcsolódó állapotkezelés. A minta nézet - és vezérlőrészei MRTK-eszközökkel és néhány egyéni szkripttel vannak implementálva. Ebben az oktatóanyagban a modell az itt implementált nézetvezérlő nélkül is használható. Ezzel az elkülönítéssel könnyedén integrálhatja az oktatóanyagban található kódot a saját alkalmazásába, ahol átveszi a tervezési minta nézetvezérlő részét.
Az MRTK bevezetésével több szkript, előfabs és eszköz is elérhető a projekthez, amelyek mostantól támogatják az interakciókat és a vizuális visszajelzéseket. Ezek az oktatóanyag-objektumok néven említett eszközök egy Unity-eszközcsomagba vannak csomagolva, amely a "\Unity\TutorialAssets\TutorialAssets.unitypackage" Azure Remote Rendering GitHub része.
- Klónozza vagy töltse le az Azure Remote Rendering Git-adattárat, ha a letöltéssel kinyeri a zip-fájlt egy ismert helyre.
- A Unity-projektben válassza az Eszközök –> Csomag importálása –> Egyéni csomag lehetőséget.
- A fájlkezelőben lépjen arra a könyvtárra, ahol klónozta vagy kibontotta az Azure Remote Rendering-adattárat, majd válassza ki a
.unitypackage
Unity –> TutorialAssets –> TutorialAssets.unitypackage helyen található elemet. - Az Importálás gombra kattintva importálhatja a csomag tartalmát a projektbe.
- A Unity Szerkesztőben válassza a Vegyes valóság eszközkészlet –> Segédprogramok –> Az MRTK Standard Shader frissítése egyszerűsített renderelési folyamathoz lehetőséget a felső menüsávon, és kövesse az utasításokat a shader frissítéséhez.
Miután az MRTK és a Tutorial Assets beállítása megtörtént, ellenőrizze, hogy a megfelelő profil van-e kiválasztva.
- Válassza a MixedRealityToolkit GameObject elemet a jelenethierarchiában.
- Az Inspector MixedRealityToolkit összetevőjében állítsa át a konfigurációs profilt az ARRMixedRealityToolkitConfigurationProfile értékre.
- A módosítások mentéséhez nyomja le a Ctrl+S billentyűkombinációt.
Ez a lépés elsősorban az MRTK-t konfigurálja az alapértelmezett HoloLens 2 profilokkal. A megadott profilok az alábbi módokon vannak előre konfigurálva:
- Kapcsolja ki a profilkészítőt (nyomja le a 9 billentyűt, hogy be- vagy kikapcsolja, vagy mondja ki a "Profiler megjelenítése/elrejtése" parancsot az eszközön).
- Kapcsolja ki a szem tekintetének kurzorát.
- Engedélyezze a Unity-egérkattintásokat, így az MRTK felhasználói felület elemeire a szimulált kéz helyett az egérrel kattinthat.
Az Alkalmazás menü hozzáadása
Az oktatóanyag legtöbb nézetvezérlője absztrakt alaposztályokon működik a konkrét osztályok helyett. Ez a minta nagyobb rugalmasságot biztosít, és lehetővé teszi számunkra a nézetvezérlők biztosítását, miközben továbbra is segítünk az Azure Remote Rendering-kód megismerésében. Az egyszerűség kedvéért a RemoteRenderingCoordinator osztály nem rendelkezik absztrakt osztálysal, és a nézetvezérlő közvetlenül a konkrét osztályon működik.
Most már hozzáadhatja az előregyártott AppMenu-t a jelenethez, hogy vizuálisan visszajelzést adjon az aktuális munkamenet állapotáról. Az AppMenu azt a modális panelt is megjeleníti, amelyet a felhasználó az alkalmazás ARR-hez való csatlakozásának engedélyezéséhez használ.
Keresse meg az AppMenu előtagot az Assets/RemoteRenderingTutorial/Prefabs/AppMenu fájlban
Húzza az AppMenu előképet a jelenetbe.
Ha megjelenik a TMP Importer párbeszédpanelje, kövesse az utasításokat a TMP Essentials importálásához. Ezután zárja be az importáló párbeszédpanelt, mivel a példákra és az extrákra nincs szükség.
Az AppMenu úgy van konfigurálva, hogy automatikusan összekapcsolja a munkamenetet, és megadja a munkamenethez való csatlakozás engedélyezéséhez szükséges modális beállítást, hogy eltávolíthassuk a korábban elhelyezett megkerülést. A RemoteRenderingCoordinator GameObject elemen távolítsa el a korábban implementált engedélyezés megkerülését a "-" gomb megnyomásával az Engedélyezéskor eseményen.
.
A nézetvezérlő teszteléséhez nyomja le a Lejátszás gombot a Unity Szerkesztőben.
A Szerkesztőben most, hogy az MRTK konfigurálva lett, a WASD billentyűkkel módosíthatja a nézet pozícióját, és a jobb egérgombot lenyomva tartva módosíthatja a nézet irányát. Próbálja ki a "vezetés" körül a jelenet egy kicsit, hogy egy kicsit érezni a vezérlők.
Az eszközön felemelheti a tenyerét az AppMenu megidézéséhez, a Unity Szerkesztőben használja az "M" gyorsbillentyűt.
Ha nem látta a menüt, nyomja le az "M" billentyűt a menü megidézéséhez. A menü a kamera közelében található az egyszerű interakció érdekében.
Az AppMenu egy felhasználói felületi elemet jelenít meg az AppMenu jobb oldalán történő engedélyezéshez. Mostantól ezt a felhasználói felületi elemet kell használnia ahhoz, hogy engedélyezze az alkalmazást a távoli renderelési munkamenetek kezeléséhez.
Az oktatóanyag folytatásához állítsa le a Unity játékát.
Modellállapot kezelése
Szükségünk van egy RemoteRenderedModel nevű új szkriptre, amely nyomon követi az állapotot, válaszol az eseményekre, aktiválja az eseményeket és a konfigurációt. A RemoteRenderedModel lényegében a modelladatok távoli elérési útját tárolja a fájlban modelPath
. Figyeli a RemoteRenderingCoordinator állapotváltozásait, hogy lássa, automatikusan be kell-e töltenie vagy ki kell-e ürítenie az általa definiált modellt. A RemoteRenderedModel objektumot tartalmazó GameObject a távoli tartalom helyi szülője.
Figyelje meg, hogy a RemoteRenderedModel szkript implementálja a BaseRemoteRenderedModel parancsprogramot, amely a Tutorial Assets része. Ez a kapcsolat lehetővé teszi, hogy a távoli modellnézet-vezérlő kösse össze a szkriptet.
Hozzon létre egy RemoteRenderedModel nevű új szkriptet a RemoteRenderingCoordinator mappában. Cserélje le a teljes tartalmat a következő kódra:
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. using Microsoft.Azure.RemoteRendering; using Microsoft.Azure.RemoteRendering.Unity; using System; using UnityEngine; using UnityEngine.Events; public class RemoteRenderedModel : BaseRemoteRenderedModel { public bool AutomaticallyLoad = true; private ModelState currentModelState = ModelState.NotReady; [SerializeField] [Tooltip("The friendly name for this model")] private string modelDisplayName; public override string ModelDisplayName { get => modelDisplayName; set => modelDisplayName = value; } [SerializeField] [Tooltip("The URI for this model")] private string modelPath; public override string ModelPath { get => modelPath.Trim(); set => modelPath = value; } public override ModelState CurrentModelState { get => currentModelState; protected set { if (currentModelState != value) { currentModelState = value; ModelStateChange?.Invoke(value); } } } public override event Action<ModelState> ModelStateChange; public override event Action<float> LoadProgress; public override Entity ModelEntity { get; protected set; } public UnityEvent OnModelNotReady = new UnityEvent(); public UnityEvent OnModelReady = new UnityEvent(); public UnityEvent OnStartLoading = new UnityEvent(); public UnityEvent OnModelLoaded = new UnityEvent(); public UnityEvent OnModelUnloading = new UnityEvent(); public UnityFloatEvent OnLoadProgress = new UnityFloatEvent(); public void Awake() { // Hook up the event to the Unity event LoadProgress += (progress) => OnLoadProgress?.Invoke(progress); ModelStateChange += HandleUnityStateEvents; } private void HandleUnityStateEvents(ModelState modelState) { switch (modelState) { case ModelState.NotReady: OnModelNotReady?.Invoke(); break; case ModelState.Ready: OnModelReady?.Invoke(); break; case ModelState.Loading: OnStartLoading?.Invoke(); break; case ModelState.Loaded: OnModelLoaded?.Invoke(); break; case ModelState.Unloading: OnModelUnloading?.Invoke(); break; } } private void Start() { //Attach to and initialize current state (in case we're attaching late) RemoteRenderingCoordinator.CoordinatorStateChange += Instance_CoordinatorStateChange; Instance_CoordinatorStateChange(RemoteRenderingCoordinator.instance.CurrentCoordinatorState); } /// <summary> /// Listen for state changes on the coordinator, clean up this model's remote objects if we're no longer connected. /// Automatically load if required /// </summary> private void Instance_CoordinatorStateChange(RemoteRenderingCoordinator.RemoteRenderingState state) { switch (state) { case RemoteRenderingCoordinator.RemoteRenderingState.RuntimeConnected: CurrentModelState = ModelState.Ready; if (AutomaticallyLoad) LoadModel(); break; default: UnloadModel(); break; } } private void OnDestroy() { RemoteRenderingCoordinator.CoordinatorStateChange -= Instance_CoordinatorStateChange; UnloadModel(); } /// <summary> /// Asks the coordinator to create a model entity and listens for coordinator state changes /// </summary> [ContextMenu("Load Model")] public override async void LoadModel() { if (CurrentModelState != ModelState.Ready) return; //We're already loaded, currently loading, or not ready to load CurrentModelState = ModelState.Loading; ModelEntity = await RemoteRenderingCoordinator.instance?.LoadModel(ModelPath, this.transform, SetLoadingProgress); if (ModelEntity != null) CurrentModelState = ModelState.Loaded; else CurrentModelState = ModelState.Error; } /// <summary> /// Clean up the local model instances /// </summary> [ContextMenu("Unload Model")] public override void UnloadModel() { CurrentModelState = ModelState.Unloading; if (ModelEntity != null) { var modelGameObject = ModelEntity.GetOrCreateGameObject(UnityCreationMode.DoNotCreateUnityComponents); Destroy(modelGameObject); ModelEntity.Destroy(); ModelEntity = null; } if (RemoteRenderingCoordinator.instance.CurrentCoordinatorState == RemoteRenderingCoordinator.RemoteRenderingState.RuntimeConnected) CurrentModelState = ModelState.Ready; else CurrentModelState = ModelState.NotReady; } /// <summary> /// Update the Unity progress event /// </summary> /// <param name="progressValue"></param> public override void SetLoadingProgress(float progressValue) { LoadProgress?.Invoke(progressValue); } }
A remoteRenderedModel a modell betöltéséhez szükséges adatokat (ebben az esetben az SAS-t vagy az builtin:// URI-t) tárolja, és nyomon követi a távoli modell állapotát. Amikor ideje betölteni a modellt, a rendszer meghívja a LoadModel
metódust a RemoteRenderingCoordinatoron, és a modellt tartalmazó entitást adja vissza referenciaként és eltávolításra.
A tesztmodell betöltése
Teszteljük az új szkriptet a tesztmodell újbóli betöltésével. Ehhez a teszthez egy Game Object objektumra van szükségünk, amely tartalmazza a szkriptet, és szülője lesz a tesztmodellnek, valamint egy virtuális fázisra, amely tartalmazza a modellt. A színpad a való világhoz képest állandó marad a WorldAnchor használatával. Rögzített fázist használunk, hogy maga a modell később is áthelyezhető legyen.
Hozzon létre egy új üres Játékobjektumot a jelenetben, és adja neki a ModelStage nevet.
World Anchor összetevő hozzáadása a ModelStage-hez
Hozzon létre egy új üres Játékobjektumot a ModelStage gyermekeként, és nevezze el TestModel néven.
Adja hozzá a RemoteRenderedModel szkriptet a TestModelhez.
Töltse ki a és a
Model Display Name
értéket aModel Path
"TestModel" és a "builtin://Engine" kifejezéssel.Helyezze a TestModel objektumot a kamera elé x = 0, y = 0, z = 3 pozícióban.
Győződjön meg arról, hogy az Automatikus betöltés be van kapcsolva.
Az alkalmazás teszteléséhez nyomja le a Play billentyűt a Unity Szerkesztőben.
Engedélyezze az engedélyezést a Csatlakozás gombra kattintva, hogy az alkalmazás létrehozhat egy munkamenetet, csatlakozhat hozzá, és automatikusan betöltheti a modellt.
Figyelje meg a konzolt, ahogy az alkalmazás végighalad az állapotán. Ne feledje, hogy egyes állapotok végrehajtása eltarthat egy ideig, és előfordulhat, hogy egy ideig nem lesznek folyamatban lévő frissítések. Végül a modellbetöltés naplói jelennek meg, majd röviddel a renderelt tesztmodell után a jelenetben.
Próbálja meg áthelyezni és elforgatni a TestModel GameObject objektumot az Inspector átalakításával, vagy a Jelenet nézetben, és figyelje meg az átalakításokat a Játék nézetben.
Blob Storage kiépítése az Azure-ban és egyéni modellbetöltés
Most megpróbálhatjuk betölteni a saját modelljét. Ehhez konfigurálnia kell a Blob Storage-t az Azure-ban, fel kell töltenie és konvertálnia kell egy modellt, majd be kell töltenie a modellt a RemoteRenderedModel szkripttel. Az egyéni modell betöltési lépéseit nyugodtan kihagyhatja, ha jelenleg nincs saját betöltési modellje.
Kövesse a Gyorsútmutató: Modell konvertálása rendereléshez című szakasz lépéseit. Az oktatóanyaghoz hagyja ki az Új modell beszúrása rövid útmutató mintaalkalmazásba szakaszt. Miután megkapta a betöltött modell közös hozzáférésű jogosultságkódjának (SAS) URI-ját, folytassa.
Egyéni modell betöltése és renderelése
Hozzon létre egy új üres GameObjectet a jelenetben, és nevezze el az egyéni modellhez hasonlóan.
Adja hozzá a RemoteRenderedModel szkriptet az újonnan létrehozott GameObjecthez.
Adja meg a
Model Display Name
modell megfelelő nevét.Töltse ki a
Model Path
modellt az Azure-beli Blob Storage kiépítése és az egyéni modellbetöltési lépésben létrehozott közös hozzáférésű jogosultságkód (SAS) URI-jával.Helyezze a GameObjectet a kamera elé x = 0, y = 0, z = 3 pozícióban.
Győződjön meg arról, hogy az Automatikus betöltés be van kapcsolva.
Az alkalmazás teszteléséhez nyomja le a Play billentyűt a Unity-szerkesztőben.
A konzol megjeleníti a munkamenet aktuális állapotát, valamint a folyamatüzeneteket betöltő modellt is, miután a munkamenet csatlakozik.
Távolítsa el az egyéni modellobjektumot a jelenetből. Ennek az oktatóanyagnak a legjobb élménye a tesztmodell. Bár az ARR-ben több modell is támogatott, ezt az oktatóanyagot úgy írtuk meg, hogy egyszerre egyetlen távoli modellt támogatjon a legjobban.
Következő lépések
Most már betöltheti saját modelljeit az Azure Remote Renderingbe, és megtekintheti őket az alkalmazásban! Ezután végigvezetjük a modellek manipulálásán.