Koordinatensysteme in Unity

Windows Mixed Reality unterstützt Apps über eine Vielzahl von Erfahrungsskalen hinweg, von apps mit ausschließlicher Ausrichtung und apps mit skaliertem Platz bis hin zu Apps im Raummaßstab. Auf HoloLens können Sie weitergehen und weltweit skalierende Apps erstellen, mit denen Benutzer mehr als 5 Meter gehen und eine gesamte Etage eines Gebäudes und darüber hinaus erkunden können.

Der erste Schritt beim Erstellen einer Mixed Reality-Erfahrung in Unity besteht darin, Koordinatensysteme zu verstehen und die Benutzeroberfläche auszuwählen, die Ihre App als Ziel verwenden soll.

Erstellen einer reinen ausrichtungsbasierten oder skalierten Benutzeroberfläche

Namespace:UnityEngine.XR
Type:XRDevice

Zum Erstellen einer reinen ausrichtungsbasierten oder besetzen Benutzeroberfläche müssen Sie Unity auf den Typ Stationärer Nachverfolgungsbereich festlegen. Der Raum für die stationäre Nachverfolgung legt das Weltkoordinatensystem von Unity fest, um den stationären Bezugsrahmen nachzuverfolgen. Im Nachverfolgungsmodus "Stationär" werden Inhalte, die im Editor direkt vor der Standardposition der Kamera platziert werden (forward ist -Z), vor dem Benutzer angezeigt, wenn die App gestartet wird.

XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);

Namespace:UnityEngine.XR
Type:InputTracking

Für eine reine Ausrichtungserfahrung , z. B. einen 360-Grad-Video-Viewer (bei dem Positionskopfupdates die Tante verfälschen würden), können Sie dann XR festlegen. InputTracking.disablePositionalTracking auf TRUE:

InputTracking.disablePositionalTracking = true;

Für eine benutzerdefinierte Benutzeroberfläche können Sie XR aufrufen, um dem Benutzer später den ursprunglichen Platz zu geben . InputTracking.Recenter-Methode :

InputTracking.Recenter();

Erstellen einer Ständigen oder Raumerfahrung

Namespace:UnityEngine.XR
Type:XRDevice

Für eine Benutzeroberfläche im Stehen oder Im Raum müssen Sie Inhalte relativ zum Boden platzieren. Sie haben den Grund dafür, dass die Etage des Benutzers die räumliche Stufe verwendet, die den definierten Ursprung der Ebene des Benutzers und die optionale Raumgrenze darstellt, die bei der ersten Ausführung eingerichtet wurde.

Um sicherzustellen, dass Unity mit seinem Weltkoordinatensystem auf Der-Boden-Ebene ausgeführt wird, können Sie festlegen und testen, ob Unity den Raumtyp RoomScale-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 umgeschaltet, um den Phasenrahmen des Verweises nachzuverfolgen.
  • Wenn SetTrackingSpaceType false zurückgibt, konnte Unity nicht zum Stageframe des Verweises wechseln, wahrscheinlich, weil der Benutzer in seiner Umgebung keine Etage eingerichtet hat. Obwohl ein falscher Rückgabewert nicht üblich ist, kann dies passieren, wenn die Stufe in einem anderen Raum eingerichtet ist und das Gerät in den aktuellen Raum verschoben wird, ohne dass der Benutzer eine neue Phase einrichtet.

Sobald Ihre App den Raumtyp "RoomScale-Nachverfolgung" erfolgreich festlegt, werden Inhalte, die auf der Ebene y=0 platziert werden, auf der Etage angezeigt. Der Ursprung bei 0, 0, 0 ist der spezifische Ort auf der Etage, an dem der Benutzer während der Einrichtung des Raumes zu gastieren hat, wobei -Z die Vorwärtsrichtung darstellt, mit der er während des Setups konfrontiert war.

Namespace:UnityEngine.Experimental.XR
Type:Boundary

Im Skriptcode können Sie dann die TryGetGeometry-Methode für den UnityEngine.Experimental.XR.Boundary-Typ aufrufen, um ein Begrenzungspolygon abzurufen und den Begrenzungstyp TrackedArea anzugeben. Wenn der Benutzer eine Grenze definiert hat (Sie erhalten eine Liste von Scheitelpunkten), ist es sicher, dem Benutzer eine Raumerfahrung bereitzustellen, in der er die von Ihnen erstellte Szene durchgehen 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 Begrenzungpolygons gestalten, um sicherzustellen, dass der Benutzer diese Objekte physisch erreichen kann, ohne teleportieren zu müssen:

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
Type:WorldAnchor

Für echte Welterfahrungen auf HoloLens, die Es Benutzern ermöglichen, mehr als 5 Meter zu erkunden, benötigen Sie neue Techniken, die über diejenigen hinausgehen, die für Raumerfahrungen verwendet werden. Eine wichtige Technik, die Sie verwenden, ist das Erstellen eines Raumankers , um einen Cluster von Hologrammen genau in der physischen Welt zu sperren, unabhängig davon, wie weit der Benutzer sich entfernt hat, und diese Hologramme dann in späteren Sitzungen wieder zu finden.

In Unity erstellen Sie einen Raumanker, indem Sie die Unity-Komponente WorldAnchor einem GameObject hinzufügen.

Hinzufügen eines Weltankers

Um einen Weltanker hinzuzufügen, rufen Sie AddComponentWorldAnchor<>() 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 leicht angepasst, um die physische Ausrichtung sicherzustellen. Verwenden Sie Persistenz , um diesen verankerten Speicherort in einer zukünftigen App-Sitzung erneut zu finden.

Entfernen eines Weltankers

Wenn Sie nicht mehr möchten, dass das GameObject an einem physischen Ort der Welt gesperrt ist und nicht beabsichtigen, es in diesem Frame zu verschieben, können Sie einfach Destroy für die 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 world Anchored GameObject

GameObject-Objekte können nicht verschoben werden, während sich ein World Anchor darauf befindet. Wenn Sie das GameObject in diesen Frame verschieben müssen, müssen Sie folgendes unternehmen:

  1. DestroyImmediate the World Anchor component
  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>();

Verarbeiten von Locatability-Änderungen

Ein WorldAnchor ist in der physischen Welt zu einem Zeitpunkt möglicherweise nicht verwendbar. 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 behandelt wird, wird das Objekt nicht an der richtigen physischen Position 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 Raumanker zwischen dem Zustand "Locatable" und "Not 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 werden Anker sofort gefunden. In diesem Fall wird diese isLocated-Eigenschaft des Ankers auf TRUE festgelegt, wenn AddComponentWorldAnchor<>() zurückgegeben wird. Daher 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 permanenten 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 sehen, dass Inhalte relativ zu diesem Anker an demselben physischen Ort gerendert werden. Dies ermöglicht gemeinsame Erfahrungen in Echtzeit.

Probieren Sie die fünfminütigen Azure Spatial Anchors Unity-Schnellstarts aus, um mit dem Erstellen freigegebener Erfahrungen in Unity zu beginnen.

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

Nächster Entwicklungsprüfpunkt

Wenn Sie die von uns festgelegte Unity-Entwicklungsprüfpunkt-Journey verfolgen, können Sie die Mixed Reality wichtigsten Bausteine erkunden. 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