Koordinatensysteme in Unity
Windows Mixed Reality unterstützt Apps für eine Vielzahl von Skalierungen, von Apps mit ausschließlicher Ausrichtung und sitzbasierter Skalierung bis hin zu Apps mit Raumskala. Auf HoloLens können Sie weiter gehen und Apps auf Weltniveau erstellen, mit denen Benutzer über 5 Meter gehen, eine ganze Etage eines Gebäudes und darüber hinaus erkunden können.
Ihr erster Schritt beim Erstellen einer Mixed Reality-Erfahrung in Unity besteht darin, Koordinatensysteme zu verstehen und die Skalierung der Erfahrung auszuwählen, auf die Ihre App ausgerichtet werden soll.
Erstellen einer reinen ausrichtungs- oder sitzbasierten Benutzeroberfläche
Namespace:UnityEngine.XR
Typ:XRDevice
Um eine reine Ausrichtungs - oder Sitzumgebung zu erstellen, müssen Sie Unity auf den Raumtyp Stationäre Nachverfolgung festlegen. Der ortsfeste 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) vor dem Benutzer angezeigt, wenn die App gestartet wird.
XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);
Namespace:UnityEngine.XR
Type:InputTracking
Für eine reine Ausrichtungserfahrung wie einen 360-Grad-Videoviewer (bei dem positionsbezogene Kopfaktualisierungen die Illusion ruinieren würden), können Sie dann XR festlegen. InputTracking.disablePositionalTracking auf true:
InputTracking.disablePositionalTracking = true;
Für eine Benutzeroberfläche mit sitzbasierter Skalierung können Sie den XR aufrufen, um dem Benutzer später den sitzbasierten Ursprung zu ermöglichen . InputTracking.Recenter-Methode :
InputTracking.Recenter();
Erstellen einer stehenden oder Raumskala-Erfahrung
Namespace:UnityEngine.XR
Typ:XRDevice
Für eine stehenden Oder Raumskala müssen Sie Inhalte relativ zum Boden platzieren. Sie begründen die Etage des Benutzers mithilfe der Raumphase, die den definierten Ursprung auf Bodenebene und die optionale Raumgrenze des Benutzers darstellt, die während des ersten Durchlaufs eingerichtet wurden.
Um sicherzustellen, dass Unity mit seinem Weltkoordinatensystem auf Bodenebene arbeitet, können Sie festlegen und testen, ob Unity den RoomScale-Nachverfolgungsraumtyp 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 Bezugs nachzuverfolgen.
- Wenn SetTrackingSpaceType false zurückgibt, konnte Unity nicht zum Phasenframe des Verweises wechseln. Dies liegt wahrscheinlich daran, dass der Benutzer keine Etage in seiner Umgebung eingerichtet hat. Obwohl ein falscher Rückgabewert nicht üblich ist, kann dies passieren, wenn die Bühne in einem anderen Raum eingerichtet wird und das Gerät in den aktuellen Raum verschoben wird, ohne dass der Benutzer eine neue Phase eingerichtet hat.
Nachdem Ihre App den RoomScale-Nachverfolgungsbereichstyp erfolgreich festgelegt hat, werden Inhalte, die auf der Ebene y=0 platziert sind, auf dem Boden angezeigt. Der Ursprung bei 0, 0, 0 ist die spezifische Stelle auf dem Boden, an der der Benutzer während der Raumeinrichtung gestanden hat, wobei -Z die Vorwärtsrichtung darstellt, die er während des Setups zugewandt hat.
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 Begrenzungspolygon abzurufen und dabei den Begrenzungstyp TrackedArea anzugeben. Wenn der Benutzer eine Grenze definiert hat (Sie erhalten eine Liste von Scheitelpunkten zurück), ist es sicher, dem Benutzer eine Raumskala zu bieten, in der er die von Ihnen erstellte Szene durchlaufen 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 anordnen, 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 Welterfahrungen auf HoloLens, bei denen Benutzer über 5 Meter wandern können, benötigen Sie neue Techniken, die über die für raumweite Umgebungen hinausgehen. Eine wichtige Technik, die Sie verwenden werden, besteht darin, einen Raumanker zu erstellen, um einen Cluster von Hologrammen genau in der physischen Welt zu sperren, unabhängig davon, wie weit der Benutzer geroamt ist, und diese Hologramme dann in späteren Sitzungen wieder zu finden.
In Unity erstellen Sie einen Raumanker, 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 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 das GameObject nicht mehr an einem physischen Weltstandort sperren möchten 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
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 Folgendes ausführen:
- DestroyImmediate die World Anchor-Komponente
- Verschieben des GameObjects
- 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 kann in der physischen Welt zu einem bestimmten Zeitpunkt möglicherweise nicht gefunden werden. 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 Verortbarkeit nicht behandelt wird, wird das Objekt nicht an der richtigen physischen Position auf der Welt angezeigt.
So werden Sie über Änderungen an der Verwertbarkeit benachrichtigt:
- Abonnieren des OnTrackingChanged-Ereignisses
- Behandeln des Ereignisses
Das OnTrackingChanged-Ereignis wird immer dann aufgerufen, wenn sich der zugrunde liegende Raumanker zwischen dem Zustand "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. Daher wird das OnTrackingChanged-Ereignis nicht ausgelöst. Ein sauber Muster wäre, ihren OnTrackingChanged-Handler mit dem anfänglichen IsLocated-Zustand nach dem Anfügen eines Ankers aufzurufen.
Anchor_OnTrackingChanged(anchor, anchor.isLocated);
Nächster Entwicklungsprüfpunkt
Wenn Sie den von uns beschriebenen Weg des Unity-Entwicklungsprüfpunkts verfolgen, sind Sie gerade dabei, die Mixed Reality Kernbausteine zu erkunden. Von hier aus können Sie mit dem nächsten Baustein fortfahren:
Oder wechseln Sie zu Mixed Reality Plattformfunktionen und APIs:
Sie können jederzeit zu den Unity-Entwicklungsprüfpunkten zurückkehren.