Wereldvergrendeling en ruimtelijke ankers in Unity
Artikel
Het is een belangrijk onderdeel van het maken van Mixed Reality toepassingen om uw hologrammen te behouden, mee te bewegen of zich in sommige gevallen ten opzichte van andere hologrammen te positioneren. In dit artikel vindt u onze aanbevolen oplossing met behulp van World Locking Tools, maar we behandelen ook het handmatig instellen van ruimtelijke ankers in uw Unity-projecten. Voordat we aan de slag gaan met code, is het belangrijk om te begrijpen hoe Unity omgaat met het coördineren van ruimte en ankers in de eigen engine.
Coördinatensystemen op wereldschaal
Wanneer u tegenwoordig games, apps voor gegevensvisualisatie of virtual reality-apps schrijft, is de gebruikelijke benadering om één absoluut wereldcoördinatensysteem op te zetten waaraan alle andere coördinaten op betrouwbare wijze kunnen worden toegewezen. In die omgeving kunt u altijd een stabiele transformatie vinden die een relatie tussen twee objecten in die wereld definieert. Als u deze objecten niet verplaatst, blijven de relatieve transformaties altijd hetzelfde. Dit soort globaal coördinatensysteem is gemakkelijk te krijgen bij het weergeven van een puur virtuele wereld waarin u alle geometrie van tevoren kent. VR-apps op ruimteschaal vormen tegenwoordig meestal dit soort absolute coördinaatsystemen op ruimteschaal met zijn oorsprong op de vloer.
Een niet-gekoppeld mixed reality-apparaat zoals HoloLens heeft daarentegen een dynamisch sensorgestuurd begrip van de wereld, waarbij de kennis van de omgeving van de gebruiker voortdurend wordt aangepast wanneer ze vele meters over een hele verdieping van een gebouw lopen. In een wereldwijde ervaring, als u al uw hologrammen in een naïef star coördinaatsysteem plaatst, zouden die hologrammen in de loop van de tijd afdrijven, hetzij gebaseerd op de wereld of ten opzichte van elkaar.
De headset kan bijvoorbeeld geloven dat twee locaties in de wereld op dit moment 4 meter uit elkaar liggen en dat begrip later verfijnen en leren dat de locaties in feite 3,9 meter uit elkaar liggen. Als deze hologrammen in eerste instantie 4 meter uit elkaar waren geplaatst in één stijf coördinatensysteem, zou een van hen altijd 0,1 meter van de echte wereld lijken.
U kunt handmatig ruimtelijke ankers in Unity plaatsen om de positie van een hologram in de fysieke wereld te behouden wanneer de gebruiker mobiel is. Dit offert echter de zelfconsistentie binnen de virtuele wereld op. Verschillende ankers bewegen zich voortdurend ten opzichte van elkaar en bewegen zich ook door de globale coördinaatruimte. In dit scenario worden eenvoudige taken, zoals de indeling, moeilijk. Fysicasimulatie kan ook problematisch zijn.
World Locking Tools (WLT) biedt u het beste van beide werelden, waarbij een enkel star coördinatensysteem wordt gestabiliseerd met behulp van een interne levering van ruimtelijke ankers verspreid over de virtuele scène terwijl de gebruiker zich verplaatst. WLT analyseert de coördinaten van de camera en die ruimtelijke ankers elk frame. In plaats van de coördinaten van alles ter wereld te wijzigen om te compenseren voor de correcties in de coördinaten van het hoofd van de gebruiker, corrigeert WLT alleen de coördinaten van het hoofd.
Kies uw wereldvergrendelingsbenadering
Gebruik indien mogelijk World Locking Tools voor het plaatsen van hologrammen.
World Locking Tools biedt een stabiel coördinatensysteem dat de zichtbare inconsistenties tussen virtuele en echte wereldmarkeringen minimaliseert. World Locking Tools vergrendelt de hele scène met een gedeelde groep ankers, in plaats van elke groep objecten te vergrendelen met het eigen afzonderlijke anker van de groep.
World Locking Tools zorgt automatisch voor interne creatie en beheer van ruimtelijke ankers. U hoeft niet te communiceren met ARAnchorManager of WorldAnchor om uw hologrammen vergrendeld te houden.
Voor Unity 2019/2020 met OpenXR of de Windows XR-invoegtoepassing gebruikt u ARAnchorManager.
Gebruik WorldAnchor voor oudere Unity-versies of WSA-projecten.
Download het hulpprogramma voor Mixed Reality functie om aan de slag te gaan met de World Locking Tools. Zie de hoofddocumentatiepagina van World Locking Tools voor koppelingen naar Overzicht, Quickstart en andere nuttige onderwerpen voor meer informatie over de basisbeginselen.
Wanneer uw project klaar is, voert u het hulpprogramma scène configureren uit vanuit Mixed Reality > World Locking Tools:
Belangrijk
Het hulpprogramma Scène configureren kan op elk gewenst moment opnieuw worden uitgevoerd. Het moet bijvoorbeeld opnieuw worden uitgevoerd als het AR-doel is gewijzigd van verouderd naar XR SDK. Als de scène al correct is geconfigureerd, heeft het uitvoeren van het hulpprogramma geen effect.
Visualizers
Tijdens de vroege ontwikkeling kan het toevoegen van visualizers handig zijn om ervoor te zorgen dat WLT is ingesteld en goed werkt. Ze kunnen worden verwijderd voor productieprestaties of, als ze om welke reden dan ook niet meer nodig zijn, met behulp van het hulpprogramma Visualizers verwijderen. Meer informatie over de visualizers vindt u in de documentatie over hulpprogramma's.
De Mixed Reality OpenXR-invoegtoepassing biedt basisankerfunctionaliteit via een implementatie van ARFoundation ARAnchorManager van Unity. Als u de basisbeginselen van ARAnchors in ARFoundation wilt leren, gaat u naar de ARFoundation-handleiding voor AR Anchor Manager.
In oudere versies van Unity maakt u een ruimtelijk anker door het onderdeel WorldAnchor Unity toe te voegen aan een GameObject.
Een wereldanker toevoegen
Als u een wereldanker wilt toevoegen, roept AddComponent<WorldAnchor>() u het gameobject aan met de transformatie die u in de echte wereld wilt verankeren.
Dit spelobject is nu verankerd aan de huidige locatie in de fysieke wereld. Mogelijk ziet u dat de unity-wereldcoördinaten in de loop van de tijd enigszins worden aangepast om fysieke uitlijning te garanderen. Zie Een wereldanker laden om deze verankerde locatie opnieuw te vinden in een toekomstige app-sessie.
Een wereldanker verwijderen
Als u niet langer wilt dat de GameObject locatie van een fysieke wereld is vergrendeld en niet van plan bent deze in dit frame te verplaatsen, roept Destroy u het onderdeel Wereldanker aan.
Destroy(gameObject.GetComponent<WorldAnchor>());
Als u dit GameObject frame wilt verplaatsen, roept DestroyImmediate u in plaats daarvan aan.
Wijzigingen in de afhandeling van de beschikbaarheid verwerken
Een wereldanker is mogelijk op een bepaald moment niet te vinden in de fysieke wereld. Unity werkt vervolgens de transformatie van het verankerde object niet bij. Deze situatie kan zich ook voordoen terwijl een app wordt uitgevoerd. Het niet afhandelen van de wijziging in de betrouwbaarheid zorgt ervoor dat het object niet op de juiste fysieke locatie in de wereld wordt weergegeven.
Op de hoogte worden gesteld van wijzigingen in de beschikbaarheid:
Abonneer u op de OnTrackingChanged gebeurtenis. De OnTrackingChanged gebeurtenis wordt aangeroepen wanneer het onderliggende ruimtelijke anker verandert tussen een status van locatable of niet-locatable.
private void Anchor_OnTrackingChanged(WorldAnchor self, bool located)
{
// This simply activates/deactivates this object and all children when tracking changes
self.gameObject.SetActiveRecursively(located);
}
Als ankers zich onmiddellijk bevinden, wordt de isLocated eigenschap van het anker ingesteld op true wanneer AddComponent<WorldAnchor>() het wordt geretourneerd. Daarom wordt de OnTrackingChanged gebeurtenis niet geactiveerd. Een schoner patroon is om de OnTrackingChanged handler aan te roepen met de beginstatus IsLocated na het bevestigen van een anker.
Ruimtelijke ankers besparen hologrammen in de echte ruimte tussen toepassingssessies. Nadat ze zijn opgeslagen in het HoloLens-ankerarchief, kunnen ruimtelijke ankers in verschillende sessies worden gevonden en geladen. Dit is een ideale terugval wanneer er geen internetverbinding is.
Belangrijk
Lokale ankers worden opgeslagen op het apparaat, terwijl Azure Spatial Anchors worden opgeslagen in de cloud. U kunt lokale en Azure-ankers in hetzelfde project hebben zonder conflict. Zie Azure Spatial Anchors voor meer informatie over het integreren van Azure-cloudservices om uw ankers op te slaan.
Standaard herstelt World Locking Tools het coördinatensysteem van Unity ten opzichte van de fysieke wereld in sessies op apparaten die ondersteuning bieden voor persistentie van lokale ruimtelijke ankers. Als u een hologram wilt weergeven op dezelfde plaats in de fysieke wereld nadat u de toepassing hebt afgesloten en opnieuw hebt uitgevoerd, hoeft de toepassing alleen dezelfde houding in het hologram te herstellen.
Als de toepassing meer controle nodig heeft, kunt u Automatisch opslaan en Automatisch laden uitschakelen in de inspector en persistentie beheren vanuit een script. Zie Systemen voor ruimtelijke coördinaten behouden voor meer informatie.
Met een API met de XRAnchorStore naam kunnen ankers tussen sessies worden bewaard. De XRAnchorStore is een weergave van de opgeslagen ankers op een apparaat. U kunt ankers uit ARAnchors de Unity-scène behouden, ankers uit de opslag laden in nieuwe ARAnchorsof ankers verwijderen uit de opslag.
Notitie
U slaat deze ankers op hetzelfde apparaat op en laadt deze op hetzelfde apparaat. Ankers tussen apparaten worden ondersteund via Azure Spatial Anchors.
Naamruimten
Voor Unity 2020 en OpenXR:
using Microsoft.MixedReality.ARSubsystems.XRAnchorStore
of Unity 2019/2020 + Windows XR-invoegtoepassing:
using UnityEngine.XR.WindowsMR.XRAnchorStore
Openbare methoden
{
// A list of all persisted anchors, which can be loaded.
public IReadOnlyList<string> PersistedAnchorNames { get; }
// Clear all persisted anchors
public void Clear();
// Load a single persisted anchor by name. The ARAnchorManager will create this new anchor and report it in
// the ARAnchorManager.anchorsChanged event. The TrackableId returned here is the same TrackableId the
// ARAnchor will have when it is instantiated.
public TrackableId LoadAnchor(string name);
// Attempts to persist an existing ARAnchor with the given TrackableId to the local store. Returns true if
// the storage is successful, false otherwise.
public bool TryPersistAnchor(TrackableId id, string name);
// Removes a single persisted anchor from the anchor store. This will not affect any ARAnchors in the Unity
// scene, only the anchors in storage.
public void UnpersistAnchor(string name);
}
Een ankerarchiefreferentie ophalen
Als u de XRAnchorStore wilt laden met Unity 2020 en OpenXR, gebruikt u de extensiemethode op het XRAnchorSubsystem, het subsysteem van een ARAnchorManager:
public static Task<XRAnchorStore> LoadAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem)
Als u de XRAnchorStore wilt laden met Unity 2019/2020 en de Windows XR-invoegtoepassing, gebruikt u de extensiemethode op het XRReferencePointSubsystem (Unity 2019) of XRAnchorSubsystem (Unity 2020), het subsysteem van een ARReferencePointManager/ARAnchorManager:
// Unity 2019 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRReferencePointSubsystem anchorSubsystem);
// Unity 2020 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem);
Een ankerarchief laden
Als u een ankerarchief wilt laden in Unity 2020 en OpenXR, opent u het als volgt vanuit het subsysteem van een ARAnchorManager:
Als u een volledig voorbeeld wilt zien van persistente/ongedaan makende ankers, bekijkt u het script Anchors -> Anchors Sample GameObject en AnchorsSample.cs in de [Mixed Reality Voorbeeldscène openXR-invoegtoepassing]((https://github.com/microsoft/OpenXR-Unity-MixedReality-Samples):
Gebruik WorldAnchor voor hologrampersistentie in oudere Unity-versies of WSA-projecten.
De WorldAnchorStore creëert holografische ervaringen waarbij hologrammen zich in specifieke posities in de echte wereld bevinden in verschillende exemplaren van de toepassing. Gebruikers kunnen afzonderlijke hologrammen vastmaken waar ze maar willen en ze later op dezelfde plek vinden tijdens app-sessies.
Met WorldAnchorStore de kunt u de locatie van wereldankers in verschillende sessies behouden. Als u hologrammen wilt behouden in verschillende sessies, moet u deze afzonderlijk bijhouden die gebruikmaken van GameObjects een bepaald wereldanker. U kunt een GameObject hoofdmap maken met een wereldanker en onderliggende hologrammen met een lokale positieverschil.
Hologrammen uit eerdere sessies laden:
Haal de WorldAnchorStoreop.
Laad de gegevens van de wereldanker-app, waarmee u de id van het wereldanker krijgt.
Laad het wereldanker op basis van de id.
Hologrammen opslaan voor toekomstige sessies:
Haal de WorldAnchorStoreop.
Sla een wereldanker op en geef een id op.
Sla app-gegevens op met betrekking tot het wereldanker, samen met de id.
Download de WorldAnchorStore
Houd een verwijzing naar de WorldAnchorStore, zodat u weet wanneer deze gereed is om een bewerking uit te voeren. Omdat deze aanroep asynchroon is, kunt u het volgende aanroepen zodra de app wordt gestart:
WorldAnchorStore.GetAsync(StoreLoaded);
StoreLoaded is de handler wanneer het WorldAnchorStore laden is voltooid:
U hebt nu een verwijzing naar de WorldAnchorStore, die u kunt gebruiken om specifieke wereldankers op te slaan en te laden.
Een wereldanker redden
Als u een wereldanker wilt redden, noemt u de wereldanker en geeft u het door in de WorldAnchorStore die u eerder hebt gekregen. Als u probeert twee ankers op te slaan in dezelfde tekenreeks, store.Save retourneert false. Verwijder de vorige opslag voordat u een nieuwe opslaat.
private void SaveGame()
{
// Save data about holograms that this world anchor positions
if (!this.savedRoot) // Only save the root once
{
this.savedRoot = this.store.Save("rootGameObject", anchor);
Assert(this.savedRoot);
}
}
Een wereldanker laden
Een wereldanker laden:
private void LoadGame()
{
// Saved data about holograms that this world anchor positions:
this.savedRoot = this.store.Load("rootGameObject", rootGameObject);
if (!this.savedRoot)
{
// Game root not saved. Re-place objects or start over.
}
}
U kunt ook gebruiken store.Delete() om een anker te verwijderen dat u eerder hebt opgeslagen en store.Clear() om alle eerder opgeslagen gegevens te verwijderen.
Bestaande ankers opsommen
Als u opgeslagen ankers wilt weergeven, roept u GetAllIdsaan.
string[] ids = this.store.GetAllIds();
for (int index = 0; index < ids.Length; index++)
{
Debug.Log(ids[index]);
}
Hologrammen behouden voor meerdere apparaten
U kunt Azure Spatial Anchors gebruiken om een duurzaam cloudanker te maken van een lokaal anker. Uw app kan het cloudanker vinden op meerdere HoloLens-, iOS- en Android-apparaten, zelfs als de apparaten niet tegelijk zijn. Omdat cloudankers permanent zijn, kunnen meerdere apparaten inhoud zien die in de loop van de tijd wordt weergegeven ten opzichte van dat anker op dezelfde fysieke locatie.