Wereldvergrendeling en ruimtelijke ankers in Unity
Artikel
Het is een belangrijk onderdeel van het maken van Mixed Reality-toepassingen om uw hologrammen op hun plaats te houden, met u mee te bewegen of in sommige gevallen zichzelf te positioneren ten opzichte van andere hologrammen. In dit artikel wordt u begeleid bij 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 in een code springen, is het belangrijk om te begrijpen hoe Unity ruimte en ankers in een eigen engine verwerkt.
Coördinaatsystemen op wereldschaal
Vandaag de dag, bij het schrijven van games, apps voor gegevensvisualisatie of virtual reality-apps, is de gebruikelijke benadering om één absoluut wereldcoördinaatsysteem tot stand te brengen waarnaar alle andere coördinaten betrouwbaar kunnen worden toegewezen. In die omgeving kunt u altijd een stabiele transformatie vinden die een relatie definieert tussen twee objecten in die wereld. Als u deze objecten niet hebt verplaatst, blijven de relatieve transformaties altijd hetzelfde. Dit soort globale coördinaatsysteem is eenvoudig te bereiken bij het weergeven van een puur virtuele wereld waar u alle geometrie van tevoren kent. Vr-apps op ruimteschaal stellen tegenwoordig meestal dit soort absolute coördinaatsysteem op ruimteschaal vast met de oorsprong ervan op de vloer.
Een niet-gekoppeld mixed reality-apparaat zoals HoloLens heeft daarentegen een dynamisch sensorgestuurd begrip van de wereld, waarbij continu de kennis in de loop van de tijd van de omgeving van de gebruiker wordt aangepast wanneer ze veel meters over een hele verdieping van een gebouw lopen. Als u al uw hologrammen in een naïef star coördinaatsysteem op wereldschaal plaatst, zouden die hologrammen in de loop van de tijd afdrijven, hetzij op basis van de wereld of ten opzichte van elkaar.
De headset kan bijvoorbeeld geloven dat twee locaties in de wereld 4 meter uit elkaar liggen en later dat begrip verfijnen, leren dat de locaties in feite 3,9 meter uit elkaar liggen. Als die hologrammen aanvankelijk 4 meter uit elkaar waren geplaatst in één stijf coördinaatsysteem, zou een van hen altijd 0,1 meter van de echte wereld verschijnen.
U kunt ruimtelijke ankers handmatig 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 in relatie tot elkaar en lopen ook door de wereldwijde coördinaatruimte. In dit scenario worden eenvoudige taken zoals indeling moeilijk. Fysicasimulatie kan ook problematisch zijn.
World Locking Tools (WLT) krijgt u het beste van beide werelden, waarbij één star coördinaatsysteem wordt gestabiliseerd met behulp van een interne levering van ruimtelijke ankers verspreid over de virtuele scène terwijl de gebruiker zich beweegt. 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 de correcties in de coördinaten van het hoofd van de gebruiker te compenseren, corrigeert WLT alleen de coördinaten van het hoofd.
Uw wereldvergrendelingsbenadering kiezen
Gebruik indien mogelijk World Locking Tools voor het positioneren van hologrammen.
World Locking Tools biedt een stabiel coördinatensysteem waarmee de zichtbare inconsistenties tussen virtuele en echte wereldmarkeringen worden geminimaliseerd. 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 verwerkt automatisch intern maken en beheren van ruimtelijke ankers. U hoeft niet te communiceren met ARAnchorManager of WorldAnchor om uw hologrammen wereldwijd vergrendeld te houden.
Gebruik ARAnchorManager voor Unity 2019/2020 met behulp van OpenXR of de Windows XR-invoegtoepassing.
Gebruik WorldAnchor voor oudere Unity-versies of WSA-projecten.
Download het Mixed Reality Feature Tool om aan de slag te gaan met de World Locking Tools. Zie de belangrijkste documentatiepagina 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 kunnen het toevoegen van visuals handig zijn om ervoor te zorgen dat WLT goed werkt 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 visualisaties 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 Manual for AR Anchor Manager.
In oudere Unity-versies maakt u een ruimtelijk anker door het WorldAnchor Unity-onderdeel 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 gameobject is nu verankerd aan de huidige locatie in de fysieke wereld. Mogelijk worden de Unity-wereldcoördinaten na verloop van tijd enigszins 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 de GameObject vergrendelde locatie van een fysieke wereld niet meer wilt en niet van plan bent dit frame te verplaatsen, roept Destroy u het onderdeel World Anchor aan.
Destroy(gameObject.GetComponent<WorldAnchor>());
Als u het GameObject frame wilt verplaatsen, roept DestroyImmediate u in plaats daarvan aan.
Je kunt een tijdje niet bewegen GameObject als er een Wereldanker op zit. Als u het GameObject volgende frame wilt verplaatsen, moet u het volgende doen:
DestroyImmediate het onderdeel World Anchor.
Verplaats de GameObject.
Voeg een nieuw World Anchor-onderdeel toe aan de GameObject.
Een Wereldanker is op een bepaald moment mogelijk niet te locatable in de fysieke wereld. Unity werkt vervolgens de transformatie van het verankerde object niet bij. Deze situatie kan ook optreden wanneer een app wordt uitgevoerd. Als de wijziging in de verwisselbaarheid niet kan worden verwerkt, wordt het object niet weergegeven op de juiste fysieke locatie ter wereld.
U ontvangt een melding over wijzigingen in de verkazing:
Abonneer u op de OnTrackingChanged gebeurtenis. De OnTrackingChanged gebeurtenis wordt aangeroepen wanneer het onderliggende ruimtelijke anker verandert tussen een status van locatable of niet te 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>() ze worden geretourneerd. Daarom wordt de OnTrackingChanged gebeurtenis niet geactiveerd. Een schoner patroon is het aanroepen van de OnTrackingChanged handler met de initiële IsLocated status na het koppelen van een anker.
Ruimtelijke ankers slaan hologrammen op in de echte ruimte tussen toepassingssessies. Zodra ze zijn opgeslagen in de HoloLens-ankeropslag, kunnen ruimtelijke ankers worden gevonden en geladen in verschillende sessies en zijn ze een ideale terugval wanneer er geen internetverbinding is.
World Locking Tools herstelt standaard het coördinaatsysteem van Unity ten opzichte van de fysieke wereld in sessies op apparaten die persistentie van lokale ruimtelijke ankers ondersteunen. Als u een hologram op dezelfde plaats in de fysieke wereld wilt weergeven nadat u de toepassing hebt afgesloten en opnieuw hebt uitgevoerd, hoeft de toepassing alleen dezelfde pose te herstellen in het hologram.
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 Persistent spatial coördinaatsystemen voor meer informatie.
World Locking Tools ondersteunt alleen lokale ankerpersistentie op HoloLens-apparaten.
Met een API met de XRAnchorStore naam 'Ankers' kunnen ankers tussen sessies worden bewaard. Dit 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 uit de opslag verwijderen.
Notitie
U slaat deze ankers op hetzelfde apparaat op en laadt deze.
Naamruimten
Voor Unity 2020 en OpenXR:
using Microsoft.MixedReality.ARSubsystems.XRAnchorStore
of Unity 2019/2020 + Windows XR Plugin:
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 naslaginformatie voor ankeropslag ophalen
Als u de XRAnchorStore wilt laden met Unity 2020 en OpenXR, gebruikt u de extensiemethode in 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 ARAnchorManager:
Als u een volledig voorbeeld van persistente/onpersisterende ankers wilt zien, bekijkt u het Ankers -> Anchors Sample GameObject en AnchorsSample.cs script in de [Mixed Reality OpenXR Plugin Sample Scene]((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 in specifieke echte wereldposities blijven voor exemplaren van de toepassing. Gebruikers kunnen afzonderlijke hologrammen vastmaken waar ze ook willen en ze later vinden op dezelfde plek via app-sessies.
Hiermee WorldAnchorStore kunt u de locatie van wereldankers in sessies behouden. Als u hologrammen tussen sessies wilt behouden, houdt u afzonderlijke traces bij die gebruikmaken van GameObjects een bepaald wereldanker. U kunt een GameObject hoofdmap maken met een wereldanker en door onderliggende hologrammen van ankers met een verschuiving van de lokale positie.
Hologrammen uit vorige sessies laden:
Haal de WorldAnchorStore.
Laad wereldanker-app-gegevens, waarmee u de id van het wereldankerpunt krijgt.
Laad het wereldanker met de id.
Hologrammen opslaan voor toekomstige sessies:
Haal de WorldAnchorStore.
Sla een wereldanker op en geef een id op.
Sla app-gegevens op die betrekking hebben op het wereldanker en de id.
De WorldAnchorStore downloaden
Houd een verwijzing naar de WorldAnchorStore, zodat u weet wanneer deze klaar is om een bewerking uit te voeren. Aangezien 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 het wereldanker en geeft u het door in de WorldAnchorStore eerder ontvangen. Als u probeert twee ankers op te slaan in dezelfde tekenreeks, store.Save retourneert u 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 store.Delete() een anker 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 het aan GetAllIds.
string[] ids = this.store.GetAllIds();
for (int index = 0; index < ids.Length; index++)
{
Debug.Log(ids[index]);
}
Volgende stappen
Deel een wereldwijd vergrendelde coördinaatruimte: