Koordinatensysteme in Unity

Windows Mixed Reality unterstützt Apps für eine breite Palette von Erfahrungsskalen, von Apps mit nur ausrichtungsbasierter und sitzbasierter Skalierung bis hin zu Apps im Raumbereich. Auf HoloLens können Sie weiter gehen und Apps auf Weltniveau erstellen, mit denen Benutzer über 5 Meter gehen und eine gesamte Etage eines Gebäudes und darüber hinaus erkunden können.

Ihr erster Schritt beim Erstellen einer Mixed Reality-Benutzeroberfläche in Unity besteht darin , Koordinatensysteme zu verstehen und die Benutzerfreundlichkeitsskala auszuwählen, auf die Ihre App abzielen soll.

Erstellen einer Nur-Orientierungs- oder Sitzumgebung

Namespace:UnityEngine.XR
Typ:XRDevice

Um eine reine Ausrichtungs - oder Sitzebene zu erstellen, müssen Sie Unity auf den Typ "Stationärer Nachverfolgungsraum" festlegen. Der stationäre Nachverfolgungsraum legt das Weltkoordinatensystem von Unity fest, um den stationären Bezugsrahmen nachzuverfolgen. Im stationären Nachverfolgungsmodus werden Inhalte, die im Editor direkt vor dem Standardspeicherort der Kamera (Vorwärts ist -Z) platziert werden, vor dem Benutzer angezeigt, wenn die App gestartet wird.

XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);

Namespace:UnityEngine.XR
Typ:InputTracking

Für eine reine Orientierungsumgebung wie einen 360-Grad-Videobetrachter (bei dem Positionskopfaktualisierungen die Illusion ruinieren würden), können Sie dann XR festlegen. InputTracking.disablePositionalTracking auf true:

InputTracking.disablePositionalTracking = true;

Für eine sitzbasierte Skalierung können Sie den XR aufrufen, damit der Benutzer später den sitzigen Ursprung neuerdings kann . InputTracking.Recenter-Methode :

InputTracking.Recenter();

Erstellen einer Erfahrung im Stand- oder Raummaßstab

Namespace:UnityEngine.XR
Typ:XRDevice

Für eine Benutzeroberfläche im Stand - oder Raummaßstab müssen Sie Inhalte relativ zum Boden platzieren. Sie begründen den Boden des Benutzers mithilfe der räumlichen Phase, die den vom Benutzer definierten Ursprung auf Bodenebene und die optionale Raumgrenze darstellt, die während der ersten Ausführung eingerichtet wurde.

Um sicherzustellen, dass Unity mit seinem Weltkoordinatensystem auf Bodenebene arbeitet, können Sie festlegen und testen, dass Unity den Raumtyp RoomScale für die Nachverfolgung verwendet:

if (XRDevice.SetTrackingSpaceType(TrackingSpaceType.RoomScale))
{
    // RoomScale mode was set successfully.  App can now assume that y=0 in Unity world coordinate represents the floor.
}
else
{
    // RoomScale mode was not set successfully.  App cannot make assumptions about where the floor plane is.
}
  • Wenn SetTrackingSpaceType "true" zurückgibt, hat Unity sein Weltkoordinatensystem erfolgreich umgestellt, um den Phasenrahmen des Referenzrahmens nachzuverfolgen.
  • Wenn SetTrackingSpaceType false zurückgibt, konnte Unity nicht zum Phasenrahmen des Referenzrahmens wechseln, wahrscheinlich weil der Benutzer keine Etage in seiner Umgebung eingerichtet hat. Ein falscher Rückgabewert ist zwar nicht üblich, kann jedoch auftreten, wenn die Phase in einem anderen Raum eingerichtet ist und das Gerät in den aktuellen Raum verschoben wird, ohne dass der Benutzer eine neue Phase eingerichtet hat.

Sobald Ihre App den RoomScale-Nachverfolgungsraumtyp erfolgreich festgelegt hat, werden Inhalte, die auf der Ebene y=0 platziert sind, auf der Etage angezeigt. Der Ursprung bei 0, 0, 0 ist der spezifische Ort auf dem Boden, an dem der Benutzer während der Raumeinrichtung stand, wobei -Z die Vorwärtsrichtung darstellt, die er während des Setups sah.

Namespace:UnityEngine.Experimental.XR
Typ:Begrenzung

Im Skriptcode können Sie dann die TryGetGeometry-Methode für den UnityEngine.Experimental.XR.Boundary-Typ aufrufen, um ein Begrenzungspolygon abzurufen und einen Begrenzungstyp von TrackedArea anzugeben. Wenn der Benutzer eine Grenze definiert hat (Sie erhalten eine Liste von Scheitelpunkten zurück), ist es sicher, dem Benutzer eine Raumebene zu bieten, in der er in der von Ihnen erstellten Szene herumlaufen kann.

Hinweis

Das System rendert die Grenze automatisch, wenn sich der Benutzer ihr nähert. Ihre App muss dieses Polygon nicht verwenden, um die Grenze selbst zu rendern. Sie können ihre Szenenobjekte jedoch mithilfe dieses Begrenzungspolygons auslegen, um sicherzustellen, dass der Benutzer diese Objekte physisch erreichen kann, ohne sich zu teleportieren:

var vertices = new List<Vector3>();
if (UnityEngine.Experimental.XR.Boundary.TryGetGeometry(vertices, Boundary.Type.TrackedArea))
{
    // Lay out your app's content within the boundary polygon, to ensure that users can reach it without teleporting.
}

Erstellen einer Erfahrung auf Weltniveau

Namespace:UnityEngine.XR.WSA
Typ:WorldAnchor

Für echte Erfahrungen auf Weltniveau auf HoloLens, mit denen Benutzer über 5 Meter wandern können, benötigen Sie neue Techniken, die über die für raumbasierte Umgebungen hinausgehen. Eine wichtige Technik, die Sie verwenden, besteht darin, einen räumlichen Anker zu erstellen, um einen Cluster von Hologrammen genau in der physischen Welt zu sperren, unabhängig davon, wie weit der Benutzer gestreut ist, und diese Hologramme dann in späteren Sitzungen wieder zu finden.

In Unity erstellen Sie einen räumlichen Anker, indem Sie die WorldAnchor Unity-Komponente zu einem GameObject hinzufügen.

Hinzufügen eines Weltankers

Um einen Weltanker hinzuzufügen, rufen Sie AddComponent<WorldAnchor>() für das Spielobjekt mit der Transformation auf, die Sie in der realen Welt verankern möchten.

WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

Das ist alles! Dieses Spielobjekt wird nun an seinem aktuellen Standort in der physischen Welt verankert . Möglicherweise werden sich die Unity-Weltkoordinaten im Laufe der Zeit leicht anpassen, um sicherzustellen, dass die physische Ausrichtung gewährleistet ist. Verwenden Sie Persistenz , um diesen verankerten Speicherort in einer zukünftigen App-Sitzung wieder zu finden.

Entfernen eines Weltankers

Wenn Sie das GameObject nicht mehr an einem physischen Standort in der Welt sperren möchten und nicht beabsichtigen, es in diesem Frame zu verschieben, können Sie einfach Destroy in der World Anchor-Komponente aufrufen.

Destroy(gameObject.GetComponent<WorldAnchor>());

Wenn Sie das GameObject in diesen Frame verschieben möchten, müssen Sie stattdessen DestroyImmediate aufrufen.

DestroyImmediate(gameObject.GetComponent<WorldAnchor>());

Verschieben eines weltweit verankerten GameObjects

GameObjects können nicht verschoben werden, während sich ein Weltanker darauf befindet. Wenn Sie das GameObject in diesem Frame verschieben müssen, müssen Sie Folgendes ausführen:

  1. DestroyImmediate die World Anchor-Komponente
  2. Verschieben des GameObject
  3. Fügen Sie dem GameObject eine neue World Anchor-Komponente hinzu.
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
gameObject.transform.position = new Vector3(0, 0, 2);
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

Behandeln von Locatability-Änderungen

Ein WorldAnchor ist möglicherweise nicht zu einem bestimmten Zeitpunkt in der physischen Welt zu finden. In diesem Fall aktualisiert Unity die Transformation des verankerten Objekts nicht. Dies kann sich auch ändern, während eine App ausgeführt wird. Wenn die Änderung der Locatability nicht verarbeitet wird, wird das Objekt nicht an der richtigen physischen Position in der Welt angezeigt.

So werden Sie über Änderungen an der Locatability benachrichtigt:

  1. Abonnieren des OnTrackingChanged-Ereignisses
  2. Behandeln des Ereignisses

Das OnTrackingChanged-Ereignis wird immer dann aufgerufen, wenn sich der zugrunde liegende räumliche Anker zwischen dem Status "locatable" und "nicht locatable" ändert.

anchor.OnTrackingChanged += Anchor_OnTrackingChanged;

Behandeln Sie dann das Ereignis:

private void Anchor_OnTrackingChanged(WorldAnchor self, bool located)
{
    // This simply activates/deactivates this object and all children when tracking changes
    self.gameObject.SetActiveRecursively(located);
}

Manchmal befinden sich Anker sofort. In diesem Fall wird diese isLocated-Eigenschaft des Ankers auf true festgelegt, wenn AddComponent<WorldAnchor>() zurückgibt. Infolgedessen wird das OnTrackingChanged-Ereignis nicht ausgelöst. Ein sauberes Muster wäre, ihren OnTrackingChanged-Handler mit dem anfänglichen IsLocated-Zustand nach dem Anfügen eines Ankers aufzurufen.

Anchor_OnTrackingChanged(anchor, anchor.isLocated);

Geräteübergreifendes Freigeben von Ankern

Verwenden Sie Azure Spatial Anchors , um einen dauerhaften Cloudanker aus einem lokalen WorldAnchor zu erstellen, den Ihre App dann auf mehreren HoloLens-, iOS- und Android-Geräten finden kann. Durch die Gemeinsame Nutzung eines gemeinsamen Raumankers auf mehreren Geräten kann jeder Benutzer Inhalte sehen, die relativ zu diesem Anker an derselben physischen Position gerendert werden. Dies ermöglicht gemeinsame Erfahrungen in Echtzeit.

Testen Sie die 5-minütigen Azure Spatial Anchors Unity-Schnellstarts, um mit dem Erstellen gemeinsamer Erfahrungen in Unity zu beginnen.

Sobald Sie azure Spatial Anchors ausführen, können Sie Anker in Unity erstellen und suchen.

Nächster Entwicklungsprüfpunkt

Wenn Sie den von uns erstellten Unity-Entwicklungsprüfpunkt verfolgen, befinden Sie sich mitten in der Erkundung der Mixed Reality kernen Bausteine. Von hier aus können Sie mit dem nächsten Baustein fortfahren:

Oder fahren Sie mit den Funktionen und APIs der Mixed Reality-Plattform fort:

Sie können jederzeit zu den Prüfpunkten für die Unity-Entwicklung zurückkehren.

Weitere Informationen