Teilen über


Koordinatensysteme in Unity

Windows Mixed Reality unterstützt Apps über eine breite Palette von Erfahrungsskalen, von Ausrichtungs- und Sitz-Apps bis hin zu Raum-Skalierungs-Apps. Auf HoloLens können Sie weiter gehen und weltweit skalierende Apps erstellen, mit denen Benutzer über 5 Meter gehen können, um eine ganze Etage eines Gebäudes und darüber hinaus zu erkunden.

Ihr erster Schritt beim Erstellen einer Mixed Reality-Erfahrung in Unity besteht darin, Koordinatensysteme zu verstehen und die Skalierung der App auszuwählen.

Erstellen einer Nur-Ausrichtungs- oder Sitzerfahrung

Namespace: UnityEngine.XR
Typ: XRDevice

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

XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);

Namespace: UnityEngine.XR
Typ: InputTracking

Für eine reine Ausrichtungserfahrung wie z. B. eine 360-Grad-Videoanzeige (bei der Positionskopfaktualisierungen die Illusion ruinieren würden), können Sie dann XR festlegen . InputTracking.disablePositionalTracking auf true:

InputTracking.disablePositionalTracking = true;

Um dem Benutzer später den Sitzursprung zu ermöglichen, können Sie den XR aufrufen. InputTracking.Recenter-Methode:

InputTracking.Recenter();

Erstellen einer steh- oder raumbasierten Erfahrung

Namespace: UnityEngine.XR
Typ: XRDevice

Für eine Steh- oder Raumerfahrung müssen Sie Inhalte relativ zum Boden platzieren. Grund für den Boden des Benutzers mithilfe der räumlichen Phase, die den definierten Ursprung des Benutzerbodens und optionale Raumgrenze darstellt, wird während der ersten Ausführung eingerichtet.

Um sicherzustellen, dass Unity mit seinem Weltkoordinatensystem auf Bodenebene arbeitet, können Sie festlegen und testen, ob Unity den Raumtyp RoomScale 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 Phasenframe des Verweises nachzuverfolgen.
  • Wenn SetTrackingSpaceType "false" zurückgibt, konnte Unity nicht zum Phasenframe des Verweises wechseln, wahrscheinlich weil der Benutzer keinen Boden in seiner Umgebung eingerichtet hat. Obwohl ein falscher Rückgabewert nicht üblich ist, kann es passieren, 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 einrichtet.

Nachdem Ihre App den Raumtyp "RoomScale-Nachverfolgung" erfolgreich festgelegt hat, werden inhalte, die auf der Ebene y=0 platziert sind, auf dem Boden 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 sie während der Einrichtung gegenüberstanden.

Namespace: UnityEngine.Experimental.XR
Typ: Grenze

Im Skriptcode können Sie dann die TryGetGeometry-Methode für den UnityEngine.Experimental.XR.Boundary-Typ aufrufen, um ein Grenz polygon abzurufen und einen Grenztyp von TrackedArea anzugeben. Wenn der Benutzer eine Grenze definiert hat (Sie erhalten eine Liste von Scheitelpunkten zurück), ist es sicher, dem Benutzer eine Raumskalaerfahrung bereitzustellen, in der er die von Ihnen erstellte Szene durchlaufen kann.

Hinweis

Das System rendert die Grenze automatisch, wenn der Benutzer sie nähert. Ihre App muss dieses Polygon nicht verwenden, um die Grenze selbst zu rendern. Sie können jedoch festlegen, dass Die Szenenobjekte mithilfe dieses Begrenzungs polygons so gestalten, dass der Benutzer diese Objekte physisch erreichen kann, ohne 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 weltweiten Erfahrung

Namespace: UnityEngine.XR.WSA
Typ: WorldAnchor

Für echte Welterfahrungen auf HoloLens, die Es Benutzern ermöglichen, über 5 Meter zu wandern, benötigen Sie neue Techniken, die über die für Raum-Skalierungserfahrungen verwendet werden. Eine wichtige Technik, die Sie verwenden werden, 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 roamiert hat, und dann diese Hologramme wieder in späteren Sitzungen 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 seiner aktuellen Position in der physischen Welt verankert - möglicherweise werden die Unity-Weltkoordinaten im Laufe der Zeit etwas angepasst, um sicherzustellen, dass die physische Ausrichtung. Verwenden Sie Persistenz , um diesen verankerten Speicherort in einer zukünftigen App-Sitzung erneut zu finden.

Entfernen eines Weltankers

Wenn Sie das GameObject nicht mehr an einen physischen Ort der Welt sperren möchten und nicht beabsichtigen, diesen Frame zu verschieben, können Sie einfach "Destroy" für die Komponente "World Anchor" aufrufen.

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

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

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

Verschieben eines weltankerten GameObjects

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

  1. DestroyImmediate die World Anchor-Komponente
  2. Verschieben des GameObjects
  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 Changes

Ein WorldAnchor kann in der physischen Welt zu einem Zeitpunkt nicht ablösbar sein. Wenn dies der Fall ist, 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 behandelt wird, wird das Objekt nicht an der richtigen physischen Position in der Welt angezeigt.

So werden Sie über Locatability Changes benachrichtigt:

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

Das OnTrackingChanged-Ereignis wird immer aufgerufen, wenn sich der zugrunde liegende räumliche Anker zwischen einem Zustand ändert, in dem es sich um einen ablösbaren Zustand oder nicht um eine Locatable-Eigenschaft ä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ückgegeben wird. Daher wird das OnTrackingChanged-Ereignis nicht ausgelöst. Ein sauberes Muster wäre das Aufrufen des OnTrackingChanged-Handlers mit dem anfänglichen IsLocated-Zustand nach dem Anfügen eines Ankers.

Anchor_OnTrackingChanged(anchor, anchor.isLocated);

Freigeben von Ankern auf allen Geräten

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 räumlichen Ankers 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.

Um mit dem Erstellen von gemeinsamen Erfahrungen in Unity zu beginnen, probieren Sie die 5-minütigen Azure Spatial Anchors Unity-Schnellstarts aus.

Sobald Sie mit Azure Spatial Anchors auf dem Laufenden sind, können Sie in Unity Verankerungen erstellen und suchen.

Nächster Entwicklungsprüfpunkt

Wenn Sie dem Weg der Unity-Entwicklungsprüfpunkt-Reise folgen, die wir eingerichtet haben, befinden Sie sich mitten in der Erkundung der Mixed Reality-Kernbausteine. 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