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 zich in sommige gevallen te positioneren ten opzichte van andere hologrammen. In dit artikel leest 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 in code gaan, is het belangrijk om te begrijpen hoe Unity omgaat met ruimte coördineren en ankers in de eigen engine.
Coördinatensystemen op wereldschaal
Tegenwoordig is bij het schrijven van games, gegevensvisualisatie-apps of virtual reality-apps de gebruikelijke aanpak om één absoluut wereldcoördinaatsysteem 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 definieert tussen twee objecten in die wereld. Als u deze objecten niet verplaatst, blijven hun relatieve transformaties altijd hetzelfde. Dit soort globale coördinatensysteem is eenvoudig te krijgen wanneer u een puur virtuele wereld weergeeft waarin u alle geometrie vooraf kent. VR-apps op kamertemperatuur vormen tegenwoordig meestal dit soort absolute coördinaatsysteem op ruimteschaal met zijn oorsprong op de vloer.
Een niet-gekoppeld mixed reality-apparaat, zoals HoloLens, heeft daarentegen een dynamisch sensorgestuurd inzicht in de wereld, waarbij de kennis van de omgeving van de gebruiker voortdurend wordt aangepast wanneer deze vele meters over een hele verdieping van een gebouw loopt. Als u al uw hologrammen in een naïef, star coördinaatsysteem zou plaatsen, zouden die hologrammen in de loop van de tijd drijven, hetzij op basis van de wereld of ten opzichte van elkaar.
De headset kan bijvoorbeeld geloven dat twee locaties in de wereld zich op 4 meter afstand bevinden en dat begrip later verfijnen en leren dat de locaties in feite 3,9 meter uit elkaar liggen. Als die hologrammen in eerste instantie 4 meter uit elkaar waren geplaatst in een enkel star coördinaatsysteem, zou een van hen altijd 0,1 meter verwijderd zijn van de echte wereld.
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 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.
Met World Locking Tools (WLT) krijgt u het beste van beide werelden, waarbij een enkel star coördinatensysteem wordt gestabiliseerd met behulp van een interne toevoer 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 de correcties in de coördinaten van het hoofd van de gebruiker te compenseren, corrigeert WLT alleen de coördinaten van het hoofd.
Kies uw wereldvergrendelingsbenadering
Gebruik indien mogelijk World Locking Tools voor het positioneren van hologrammen.
World Locking Tools biedt een stabiel coördinatensysteem dat de zichtbare inconsistenties tussen virtuele en echte markeringen 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.
Wereldvergrendeling instellen
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.
Geautomatiseerde installatie
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 in XR SDK. Als de scène al correct is geconfigureerd, heeft het uitvoeren van het hulpprogramma geen effect.
Visualisaties
Tijdens de vroege ontwikkeling kan het toevoegen van visualisaties nuttig zijn om ervoor te zorgen dat WLT correct wordt 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 visualisaties vindt u in de documentatie over hulpprogramma's.
De Mixed Reality OpenXR-invoegtoepassing biedt basisfunctionaliteit voor ankers 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.
Naamruimte:UnityEngine.XR.WSA
Type:WorldAnchor
Een belangrijke techniek is het maken van een ruimtelijk anker om een cluster met hologrammen precies op zijn plaats te vergrendelen in de fysieke wereld, ongeacht hoe ver de gebruiker heeft geroerd, en die hologrammen vervolgens in latere sessies opnieuw te vinden.
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.
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();
Dit gameobject 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 iets 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 om het in dit frame te verplaatsen, roept u Destroy het onderdeel World Anchor aan.
Destroy(gameObject.GetComponent<WorldAnchor>());
Als u dit GameObject frame wilt verplaatsen, roept DestroyImmediate u in plaats daarvan aan.
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
Een world anchored gameobject verplaatsen
Je kunt niet bewegen zolang GameObject er een wereldanker op zit. Als u dit frame wilt verplaatsen, moet u het GameObject volgende doen:
-
DestroyImmediate het onderdeel World Anchor.
- Verplaats de
GameObject.
- Voeg een nieuw World Anchor-onderdeel toe aan de
GameObject.
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
gameObject.transform.position = new Vector3(0, 0, 2);
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();
Wijzigingen in locatability verwerken
Een wereldanker is misschien niet op een bepaald moment in de fysieke wereld te vinden. 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 locatability 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 toestand van bekaatsbaar of niet-locatable.
anchor.OnTrackingChanged += Anchor_OnTrackingChanged;
De gebeurtenis afhandelen.
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>() wordt geretourneerd. Daarom wordt de OnTrackingChanged gebeurtenis niet geactiveerd. Een schoner patroon is om de OnTrackingChanged handler aan te roepen met de initiële IsLocated status na het bevestigen van een anker.
Anchor_OnTrackingChanged(anchor, anchor.isLocated);
Permanente wereldvergrendeling
Ruimtelijke ankers slaan hologrammen op in de echte ruimte tussen toepassingssessies. Zodra deze zijn opgeslagen in het HoloLens-ankerarchief, kunnen ruimtelijke ankers worden gevonden en geladen in verschillende sessies en zijn ze een ideale terugval wanneer er geen internetverbinding is.
Standaard herstellen World Locking Tools het coördinaatsysteem van Unity ten opzichte van de fysieke wereld in sessies op apparaten die persistentie van lokale ruimtelijke ankers ondersteunen. Als u wilt dat een hologram op dezelfde plaats in de fysieke wereld wordt weergegeven 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.
World Locking Tools ondersteunt alleen lokale ankerpersistentie op HoloLens-apparaten.
Met een API met de XRAnchorStore naam kunnen ankers tussen sessies worden behouden. 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.
Opmerking
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-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);
}
Referentie voor ankeropslag 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 ankeropslag laden
Als u een ankeropslag in Unity 2020 en OpenXR wilt laden, opent u deze als volgt vanuit het subsysteem van een ARAnchorManager:
ARAnchorManager arAnchorManager = GetComponent<ARAnchorManager>();
XRAnchorStore anchorStore = await arAnchorManager.subsystem.LoadAnchorStoreAsync();
of met Unity 2019/2020 en de Windows XR-invoegtoepassing:
// Unity 2019
ARReferencePointManager arReferencePointManager = GetComponent<ARReferencePointManager>();
XRAnchorStore anchorStore = await arReferencePointManager.subsystem.TryGetAnchorStoreAsync();
// Unity 2020
ARAnchorManager arAnchorManager = GetComponent<ARAnchorManager>();
XRAnchorStore anchorStore = await arAnchorManager.subsystem.TryGetAnchorStoreAsync();
Als u een volledig voorbeeld wilt zien van persistente/ongedaan makende ankers, bekijkt u het GameObject en het AnchorsSample.cs-script Anchors -> Anchors in de voorbeeldscène [Mixed Reality OpenXR-invoegtoepassing]((https://github.com/microsoft/OpenXR-Unity-MixedReality-Samples):
Gebruik WorldAnchor voor hologrampersistentie in oudere Unity-versies of WSA-projecten.
Naamruimte:UnityEngine.XR.WSA.Persistence
Klasse:WorldAnchorStore
De WorldAnchorStore maakt holografische ervaringen waarbij hologrammen zich in specifieke posities in de echte wereld bevinden in exemplaren van de toepassing. Gebruikers kunnen afzonderlijke hologrammen vastmaken waar ze maar willen en ze later op dezelfde plek vinden via app-sessies.
Met de WorldAnchorStore kunt u de locatie van wereldankers in verschillende sessies behouden. Als u hologrammen in verschillende sessies wilt behouden, houdt u de hologrammen afzonderlijk bij die gebruikmaken van GameObjects een bepaald wereldanker. U kunt een GameObject hoofdmap maken met een wereldanker en onderliggende hologrammen met een lokale positieverplaatsing.
Hologrammen uit eerdere sessies laden:
- Haal de
WorldAnchorStoreop.
- Laad de gegevens van de world anchor-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 klaar 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:
private void StoreLoaded(WorldAnchorStore store)
{
this.store = store;
}
U hebt nu een verwijzing naar de WorldAnchorStore, die u kunt gebruiken om specifieke wereldankers op te slaan en te laden.
Een wereldanker opslaan
Als u een wereldanker wilt opslaan, noemt u het 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 onwaar. 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]);
}
Volgende stappen
Deel een wereld vergrendelde coördinaatruimte:
Meer informatie over ruimtelijke toewijzing:
Terug naar de Unity-ontwikkelcontrolepunten:
Zie ook