Bewegungscontroller in Unity

Es gibt zwei wichtige Möglichkeiten, um in Unity, Handgesten und Bewegungscontrollern in HoloLens und immersiven HMD Maßnahmen zu ergreifen. Sie greifen auf die Daten für beide Quellen räumlicher Eingaben über die gleichen APIs in Unity zu.

Unity bietet zwei primäre Möglichkeiten, auf räumliche Eingabedaten für Windows Mixed Reality zuzugreifen. Die gängigen Input.GetButton/Input.GetAxis-APIs funktionieren über mehrere Unity XR-SDKs hinweg, während die InteractionManager/GestureRecognizer-API speziell für Windows Mixed Reality den vollständigen Satz räumlicher Eingabedaten verfügbar macht.

Unity XR-Eingabe-APIs

Für neue Projekte empfehlen wir die Verwendung der neuen XR-Eingabe-APIs von Anfang an.

Weitere Informationen zu den XR-APIs finden Sie hier.

Unity-Schaltfläche/Achsenzuordnungstabelle

Der Eingabe-Manager von Unity für Windows Mixed Reality Bewegungscontroller unterstützt die schaltflächen- und Achsen-IDs, die unten über die Input.GetButton/GetAxis-APIs aufgeführt sind. Die Spalte "Windows MR-specific" bezieht sich auf Eigenschaften, die vom InteractionSourceState-Typ verfügbar sind. Jede dieser APIs wird in den folgenden Abschnitten ausführlich beschrieben.

Die Schaltflächen-/Achsen-ID-Zuordnungen für Windows Mixed Reality entsprechen im Allgemeinen den Oculus-Schaltflächen-/Achsen-IDs.

Die Schaltflächen-/Achsen-ID-Zuordnungen für Windows Mixed Reality unterscheiden sich von openVR-Zuordnungen auf zwei Arten:

  1. Die Zuordnung verwendet Touchpad-IDs, die sich von einem Daumenstick unterscheiden, um Controller sowohl mit Daumensticks als auch touchpads zu unterstützen.
  2. Die Zuordnung verhindert, dass die A- und X-Schaltflächen-IDs für die Menüschaltflächen überladen werden, um sie für die physischen ABXY-Schaltflächen verfügbar zu lassen.
EingabeAllgemeine Unity-APIs
(Input.GetButton/GetAxis)
Windows MR-spezifische Eingabe-API
(XR. WSA. Eingabe)
Linke Rechte Hand
Auslöser auswählen Achse 9 = 1,0 Achse 10 = 1,0 selectPressed
Auslöser analogen Wert auswählen Achse 9 Achse 10 selectPressedAmount
Auslöser auswählen, teilweise gedrückt Schaltfläche 14 (Gamepad compat) Schaltfläche 15 (Gamepad compat) selectPressedAmount > 0.0
Menüschaltfläche gedrückt Schaltfläche 6* Schaltfläche 7* menuPressed
Grifftaste gedrückt Achse 11 = 1,0 (keine analogen Werte)
Schaltfläche 4 (Gamepad compat)
Achse 12 = 1,0 (keine analogen Werte)
Schaltfläche 5 (Gamepadkompat)
Begriffen
Thumbstick X (links: -1.0, rechts: 1,0) Achse 1 Achse 4 thumbstickPosition.x
Daumenstick Y (oben: -1,0, unten: 1,0) Achse 2 Achse 5 thumbstickPosition.y
Fingerstick gedrückt Schaltfläche 8 Schaltfläche 9 DaumenstickPressed
Touchpad X (links: -1.0, rechts: 1,0) Achse 17* Achse 19* touchpadPosition.x
Touchpad Y (oben: -1.0, unten: 1,0) Achse 18* Achse 20* touchpadPosition.y
Touchpad mit Toucheingabe Schaltfläche 18* Schaltfläche 19* TouchpadTouched
Touchpad gedrückt Schaltfläche 16* Schaltfläche 17* touchpadPressed
6DoF-Griff-Pose oder Zeiger-Pose Nur Griffpose : XR. InputTracking.GetLocalPosition
Xr. InputTracking.GetLocalRotation
Übergeben Sie Grip oder Zeiger als Argument: sourceState.sourcePose.TryGetPosition
sourceState.sourcePose.TryGetRotation
Nachverfolgungsstatus Positionsgenauigkeit und Quellverlustrisiko nur über MR-spezifische API verfügbar sourceState.sourcePose.positionAccuracy
sourceState.properties.sourceLossRisk

Hinweis

Diese Schaltflächen-/Achsen-IDs unterscheiden sich von den IDs, die Unity aufgrund von Kollisionen in den von Gamepads, Oculus Touch und OpenVR verwendeten Zuordnungen verwendet.

OpenXR

Informationen zu Mixed Reality-Interaktionen in Unity finden Sie im Unity-Handbuch für Unity XR Input. Diese Unity-Dokumentation behandelt die Zuordnungen von controllerspezifischen Eingaben zu allgemeineren InputFeatureUsages, wie verfügbare XR-Eingaben identifiziert und kategorisiert werden können, wie Daten aus diesen Eingaben gelesen werden und vieles mehr.

Das Mixed Reality OpenXR Plug-In bietet zusätzliche Eingabeinteraktionsprofile, die den standardmäßigen InputFeatureUsages wie unten beschrieben zugeordnet sind:

InputFeatureUsage HP Reverb G2 Controller (OpenXR) HoloLens Hand (OpenXR)
primary2DAxis Joystick
primary2DAxisClick Joystick - Klicken Sie auf
Trigger (trigger) Trigger
packen Packen Luft tippen oder drücken
primaryButton [X/A] - Drücken Sie In die Luft tippen
secondaryButton [Y/B] - Drücken Sie
gripButton Griff - Drücken
triggerButton Trigger - Drücken
menuButton Menü

Griffpose vs. Zeigepose

Windows Mixed Reality unterstützt Bewegungscontroller in einer Vielzahl von Formfaktoren. Jedes Controllerdesign unterscheidet sich in seiner Beziehung zwischen der Handposition des Benutzers und der natürlichen "Vorwärtsrichtung", die Apps beim Rendern des Controllers verwenden sollten.

Um diese Controller besser darzustellen, gibt es zwei Arten von Posen, die Sie für jede Interaktionsquelle, die Griffpose und die Zeigerpose untersuchen können. Sowohl die Grip-Pose als auch die Zeiger-Posenkoordinaten werden von allen Unity-APIs in globalen Unity-Weltkoordinaten ausgedrückt.

Griff-Pose

Die Griffposition stellt die Position der Handfläche des Benutzers dar, die entweder von einem HoloLens erkannt oder einen Bewegungscontroller gehalten wird.

Bei immersiven Headsets wird die Griffpose am besten verwendet, um die Hand des Benutzers oder ein Objekt zu rendern, das in der Hand des Benutzers gehalten wird. Die Griffpose wird auch beim Visualisieren eines Bewegungscontrollers verwendet. Das renderbare Modell , das von Windows für einen Bewegungscontroller bereitgestellt wird, verwendet die Griffpose als Ursprung und Drehzentrum.

Die Griffpose wird speziell wie folgt definiert:

  • Die Griffposition: Das Palmzentriert, wenn der Controller natürlich hält, nach links oder rechts, um die Position innerhalb des Griffs zu zentrieren. Auf dem Windows Mixed Reality Bewegungscontroller richtet sich diese Position in der Regel an der Schaltfläche "Greif" aus.
  • Die Rechte Achse des Griffs: Wenn Sie Ihre Hand vollständig öffnen, um eine flache 5-Finger-Pose zu bilden, ist der Strahl, der normal für Ihre Handfläche ist (vorwärts von der linken Hand, rückwärts von der rechten Handfläche)
  • Die Vorwärtsachse der Griffausrichtung: Wenn Sie ihre Hand teilweise schließen (wie wenn Sie den Controller halten), zeigt der Strahl, der durch die Röhre durch Ihre Finger ohne Daumen "vorwärts" zeigt.
  • Die Up-Achse des Griffs: Die up-Achse, die von den Definitionen "Rechts" und "Vorwärts" impliziert wird.

Sie können über die anbieterübergreifende Eingabe-API (XR) von Unity auf den Griff zugreifen. InputTracking. GetLocalPosition/Rotation) oder über die Windows MR-spezifische API (sourceState.sourcePose.TryGetPosition/Rotation), die Posendaten für den Grip-Knoten anfordert.

Zeigerpose

Die Zeigerposition stellt die Spitze des Controllers dar, der vorwärts zeigt.

Die vom System bereitgestellte Zeigerpose wird am besten zum Raycast verwendet, wenn Sie das Controllermodell selbst rendern. Wenn Sie ein anderes virtuelles Objekt anstelle des Controllers rendern, z. B. eine virtuelle Waffe, sollten Sie mit einem Ray zeigen, der für dieses virtuelle Objekt am natürlichsten ist, z. B. einen Ray, der entlang des Laufs des app-definierten Waffenmodells reist. Da Benutzer das virtuelle Objekt und nicht den physischen Controller sehen können, ist das Zeigen mit dem virtuellen Objekt wahrscheinlich natürlicher für diejenigen, die Ihre App verwenden.

Derzeit ist die Zeigerposition nur über die Windows MR-spezifische API, sourceState.sourcePose.TryGetPosition/Rotation, die in InteractionSourceNode.Pointer als Argument übergeben wird, verfügbar.

OpenXR

Sie haben Zugriff auf zwei Gruppen von Posen über OpenXR-Eingabeinteraktionen:

  • Die Griffpose zum Rendern von Objekten in der Hand
  • Ziel ist es, auf die Welt zu zeigen.

Weitere Informationen zu diesem Design und die Unterschiede zwischen den beiden Posen finden Sie in der OpenXR-Spezifikation - Eingabeunterpfade.

Posen, die von den InputFeatureUsages DevicePosition, DeviceRotation, DeviceVelocity und DeviceAngularVelocity bereitgestellt werden, stellen alle die OpenXR-Griffposition dar. InputFeatureUsages im Zusammenhang mit Griffposen werden in Unitys CommonUsages definiert.

Posen, die von den InputFeatureUsages PointerPosition, PointerRotation, PointerVelocity und PointerAngularVelocity bereitgestellt werden, stellen alle die OpenXR-Zielposition dar. Diese InputFeatureUsages sind in allen enthaltenen C#-Dateien nicht definiert, sodass Sie Ihre eigenen InputFeatureUsages wie folgt definieren müssen:

public static readonly InputFeatureUsage<Vector3> PointerPosition = new InputFeatureUsage<Vector3>("PointerPosition");

Haptik

Informationen zur Verwendung von Haptik im XR-Eingabesystem von Unity finden Sie im Unity Manual for Unity XR Input - Haptics.

Controllerverfolgungsstatus

Wie die Headsets erfordert der Windows Mixed Reality Bewegungscontroller keine Einrichtung externer Nachverfolgungssensoren. Stattdessen werden die Controller von Sensoren im Headset selbst nachverfolgt.

Wenn der Benutzer die Controller aus dem Sichtfeld des Headsets verschiebt, leitet Windows in den meisten Fällen weiterhin Controllerpositionen ab. Wenn der Controller die visuelle Nachverfolgung für lange genug verloren hat, wird die Position des Controllers auf ungefähre Genauigkeitspositionen abgesetzt.

An diesem Punkt sperrt das System den Controller an den Benutzer, verfolgt die Position des Benutzers, während er sich bewegt, während er weiterhin die wahre Ausrichtung des Controllers mithilfe seiner internen Ausrichtungssensoren verfügbar macht. Viele Apps, die Controller verwenden, um auf UI-Elemente zu zeigen und zu aktivieren, können normal ausgeführt werden, während dies in ungefährer Genauigkeit erfolgt, ohne dass der Benutzer nicht benachrichtigt wird.

Gründe für den Status der Nachverfolgung explizit

Apps, die Positionen basierend auf dem Nachverfolgungszustand anders behandeln möchten, können weiter gehen und Eigenschaften des Controllerstatus überprüfen, z. B. SourceLossRisk und PositionAccuracy:

Nachverfolgungsstatus SourceLossRisk PositionAccuracy TryGetPosition
Hohe Genauigkeit < 1.0 Hoch true
Hohe Genauigkeit (Risiko eines Verlusts) == 1.0 Hoch true
Ungefähre Genauigkeit == 1.0 Ungefähr true
Keine Position == 1.0 Ungefähr false

Diese Bewegungscontrollernachverfolgungszustände werden wie folgt definiert:

  • Hohe Genauigkeit: Während sich der Bewegungscontroller innerhalb des Ansichtsfelds des Headsets befindet, stellt er in der Regel hohe Genauigkeitspositionen bereit, basierend auf visueller Nachverfolgung. Ein Bewegungscontroller, der das Sichtfeld momentariell verlässt oder momentariell von den Headsetsensoren verdeckt wird (z. B. durch die andere Hand des Benutzers), wird weiterhin hochgenaue Posen für eine kurze Zeit zurückgeben, basierend auf der inertialen Nachverfolgung des Controllers selbst.
  • Hohe Genauigkeit (Risiko eines Verlusts): Wenn der Benutzer den Bewegungscontroller an den Rand des Sichtfelds des Headsets bewegt, kann das Headset bald die Position des Controllers nicht visuell nachverfolgen. Die App weiß, wann der Controller diese FOV-Grenze erreicht hat, indem der SourceLossRisk 1.0 erreicht. An diesem Punkt kann die App festlegen, dass Controllergesten angehalten werden, die einen stetigen Datenstrom von qualitativ hochwertigen Posen erfordern.
  • Ungefähre Genauigkeit: Wenn der Controller die visuelle Nachverfolgung für lange genug verloren hat, wird die Position des Controllers auf ungefähre Genauigkeitspositionen abgesetzt. An diesem Punkt sperrt das System den Controller an den Benutzer, verfolgt die Position des Benutzers, während er sich bewegt, während er weiterhin die wahre Ausrichtung des Controllers mithilfe seiner internen Ausrichtungssensoren verfügbar macht. Viele Apps, die Controller verwenden, um auf UI-Elemente zu zeigen und zu aktivieren, können normal ausgeführt werden, während sie ungefähr korrekt sind, ohne dass der Benutzer notiert wird. Apps mit schwereren Eingabeanforderungen können sich entscheiden, diesen Abbruch von hoher Genauigkeit bis zur ungefähren Genauigkeit zu spüren, indem sie die PositionAccuracy-Eigenschaft überprüfen, z. B. dem Benutzer einen großzügigeren Hitbox auf off-screen-Zielen während dieser Zeit zu geben.
  • Keine Position: Während der Controller eine ungefähre Genauigkeit für lange Zeit ausführen kann, weiß das System manchmal, dass sogar eine körpersperrte Position derzeit nicht sinnvoll ist. Beispielsweise wurde ein Controller, der aktiviert wurde, möglicherweise nie visuell beobachtet, oder ein Benutzer kann einen Controller ablegen, der dann von einer anderen Person aufgenommen wird. Zu diesen Zeiten stellt das System keine Position für die App bereit, und TryGetPosition gibt "false" zurück.

Allgemeine Unity-APIs (Input.GetButton/GetAxis)

Namespace:UnityEngine,UnityEngine.XR
Typen: Eingabe, XR. InputTracking

Unity verwendet derzeit seine allgemeinen Input.GetButton/Input.GetAxis-APIs, um Eingaben für das Oculus SDK, das OpenVR SDK und Windows Mixed Reality verfügbar zu machen, einschließlich Hände und Bewegungscontrollern. Wenn Ihre App diese APIs für die Eingabe verwendet, kann sie Bewegungscontroller problemlos über mehrere XR-SDKs hinweg unterstützen, einschließlich Windows Mixed Reality.

Abrufen des gedrückten Zustands einer logischen Schaltfläche

Um die allgemeinen Unity-Eingabe-APIs zu verwenden, beginnen Sie in der Regel mit der Verkabelung von Schaltflächen und Achsen mit logischen Namen im Unity Input Manager, um eine Schaltfläche oder Achsen-IDs an jeden Namen zu binden. Sie können dann Code schreiben, der auf diesen logischen Schaltflächen-/Achsennamen verweist.

Wenn Sie beispielsweise die Triggerschaltfläche des linken Bewegungscontrollers der Sendeaktion zuordnen möchten, wechseln Sie zu ">Projekteinstellungen > bearbeiten" innerhalb von Unity, und erweitern Sie die Eigenschaften des Abschnitts "Absenden" unter "Achsen". Ändern Sie die Eigenschaft "Positive Schaltfläche " oder "Alt Positive Button" , um die Joystickschaltfläche 14 zu lesen, wie folgt:

InputManager von Unity
Unity InputManager

Ihr Skript kann dann mithilfe von Input.GetButton nach der Übermittlungsaktion suchen:

if (Input.GetButton("Submit"))
{
  // ...
}

Sie können weitere logische Schaltflächen hinzufügen, indem Sie die Eigenschaft "Size " unter "Achsen" ändern.

Direktes Abrufen des gedrückten Zustands einer physischen Schaltfläche

Sie können auch manuell auf Schaltflächen zugreifen, indem Sie den vollqualifizierten Namen verwenden, indem Sie Input.GetKey verwenden:

if (Input.GetKey("joystick button 8"))
{
  // ...
}

Abrufen der Hand- oder Bewegungssteuerungs-Pose

Sie können über XR auf die Position und Drehung des Controllers zugreifen . InputTracking:

Vector3 leftPosition = InputTracking.GetLocalPosition(XRNode.LeftHand);
Quaternion leftRotation = InputTracking.GetLocalRotation(XRNode.LeftHand);

Hinweis

Der obige Code stellt die Grip-Pose des Controllers dar (wobei der Benutzer den Controller hält), der für das Rendern eines Schwerts oder einer Waffe in der Hand des Benutzers oder eines Modells des Controllers selbst nützlich ist.

Die Beziehung zwischen dieser Grip-Pose und der Zeiger-Pose (wo die Spitze des Controllers zeigt) kann sich über Controller unterscheiden. In diesem Moment ist der Zugriff auf die Zeiger-Pose des Controllers nur über die MR-spezifische Eingabe-API möglich, die in den nachstehenden Abschnitten beschrieben wird.

Windows-spezifische APIs (XR). WSA. Eingabe)

Achtung

Wenn Ihr Projekt eine der XR-Elemente verwendet. WSA-APIs werden diese für die XR SDK in zukünftigen Unity-Versionen schrittweise beendet. Für neue Projekte empfehlen wir die Verwendung des XR SDK von Anfang an. Weitere Informationen zum XR-Eingabesystem und apIs finden Sie hier.

Namespace:UnityEngine.XR.WSA.Input
Typen: InteractionManager,InteractionSourceState, InteractionSource, InteractionSourceProperties, InteractionSourceKind, InteractionSourceLocation

Um ausführlichere Informationen zu Windows Mixed Reality Handeingaben (für HoloLens) und Bewegungscontroller zu erhalten, können Sie die Windows-spezifischen Raumeingabe-APIs unter dem UnityEngine.XR.WSA.Input-Namespace verwenden. Dadurch können Sie auf zusätzliche Informationen zugreifen, z. B. die Positionsgenauigkeit oder die Quellart, mit der Sie Hände und Controller voneinander trennen können.

Umfrage für den Zustand der Hände und Bewegungscontroller

Sie können den Zustand dieses Frames für jede Interaktionsquelle (Hand- oder Bewegungscontroller) mithilfe der GetCurrentReading-Methode abfragen.

var interactionSourceStates = InteractionManager.GetCurrentReading();
foreach (var interactionSourceState in interactionSourceStates) {
    // ...
}

Jede InteractionSourceState , die Sie zurück erhalten, stellt eine Interaktionsquelle zur aktuellen Zeit dar. Der InteractionSourceState stellt Informationen wie:

  • Welche Arten von Drücken auftreten (Select/Menu/Grasp/Touchpad/Thumbstick)

    if (interactionSourceState.selectPressed) {
         // ...
    }
    
  • Andere Daten, die für Bewegungscontroller spezifisch sind, z. B. die XY-Koordinaten und /oder die XY-Koordinaten und den touchierten Zustand des Touchsticks

    if (interactionSourceState.touchpadTouched && interactionSourceState.touchpadPosition.x > 0.5) {
         // ...
    }
    
  • Das InteractionSourceKind, um zu wissen, ob die Quelle eine Hand oder ein Bewegungscontroller ist

    if (interactionSourceState.source.kind == InteractionSourceKind.Hand) {
         // ...
    }
    

Abfrage für vorwärtsvorgesagte Rendering-Posen

  • Bei der Abfrage von Interaktionsquellendaten aus Händen und Controllern werden die Posen, die Sie erhalten, für den Moment in der Zeit, in der die Photonen dieses Frames die Augen des Benutzers erreichen. Vorwärtsvorgesagte Posen werden am besten zum Rendern des Controllers oder eines gehaltenen Objekts für jeden Frame verwendet. Wenn Sie auf eine bestimmte Pressemitteilung oder Veröffentlichung mit dem Controller abzielen, ist dies am genauesten, wenn Sie die unten beschriebenen historischen Ereignis-APIs verwenden.

    var sourcePose = interactionSourceState.sourcePose;
    Vector3 sourceGripPosition;
    Quaternion sourceGripRotation;
    if ((sourcePose.TryGetPosition(out sourceGripPosition, InteractionSourceNode.Grip)) &&
         (sourcePose.TryGetRotation(out sourceGripRotation, InteractionSourceNode.Grip))) {
         // ...
    }
    
  • Sie können auch die vorausgesagte Kopfvorlage für diesen aktuellen Frame erhalten. Wie bei der Quell-Pose ist dies nützlich für das Rendern eines Cursors, obwohl das Ziel einer bestimmten Presse oder Veröffentlichung am genauesten ist, wenn Sie die unten beschriebenen historischen Ereignis-APIs verwenden.

    var headPose = interactionSourceState.headPose;
    var headRay = new Ray(headPose.position, headPose.forward);
    RaycastHit raycastHit;
    if (Physics.Raycast(headPose.position, headPose.forward, out raycastHit, 10)) {
         var cursorPos = raycastHit.point;
         // ...
    }
    

Behandeln von Interaktionsquellenereignissen

Um Eingabeereignisse zu behandeln, während sie mit ihren genauen historischen Posendaten auftreten, können Sie Interaktionsquellenereignisse anstelle der Abfrage behandeln.

So behandeln Sie Interaktionsquellenereignisse:

  • Registrieren Sie sich für ein InteractionManager-Eingabeereignis . Für jede Art von Interaktionsereignis, an dem Sie interessiert sind, müssen Sie es abonnieren.

    InteractionManager.InteractionSourcePressed += InteractionManager_InteractionSourcePressed;
    
  • Behandeln Sie das Ereignis. Nachdem Sie ein Interaktionsereignis abonniert haben, erhalten Sie den Rückruf bei Bedarf. Im SourcePressed-Beispiel wird dies nach der Erkennung der Quelle und vor der Veröffentlichung oder verloren gehen.

    void InteractionManager_InteractionSourceDetected(InteractionSourceDetectedEventArgs args)
         var interactionSourceState = args.state;
    
         // args.state has information about:
            // targeting head ray at the time when the event was triggered
            // whether the source is pressed or not
            // properties like position, velocity, source loss risk
            // source id (which hand id for example) and source kind like hand, voice, controller or other
    }
    

So beenden Sie die Behandlung eines Ereignisses

Sie müssen die Behandlung eines Ereignisses beenden, wenn Sie nicht mehr an dem Ereignis interessiert sind, oder Sie das Objekt zerstören, das das Ereignis abonniert hat. Um die Behandlung des Ereignisses zu beenden, melden Sie sich vom Ereignis ab.

InteractionManager.InteractionSourcePressed -= InteractionManager_InteractionSourcePressed;

Liste der Interaktionsquellenereignisse

Die verfügbaren Interaktionsquellenereignisse sind:

  • InteractionSourceDetected (Quelle wird aktiv)
  • InteractionSourceLost (wird inaktiv)
  • InteractionSourcePressed (tippen, Schaltfläche drücken oder "Auswählen" aus)
  • InteractionSourceReleased (Ende eines Tippens, einer Schaltfläche, die veröffentlicht oder das Ende von "Select" ausgelöst wurde)
  • InteractionSourceUpdated (verschiebt oder ändert anderen Zustand)

Ereignisse für historische Zielstellungen, die am genauesten mit einer Presse oder Veröffentlichung übereinstimmen

Die zuvor beschriebenen Umfrage-APIs geben Ihrer App vorwärts vorhergesagte Posen. Während die vorhergesagten Posen für das Rendern des Controllers oder eines virtuellen Handheld-Objekts am besten geeignet sind, sind zukünftige Posen nicht optimal für das Ziel, aus zwei wichtigen Gründen:

  • Wenn der Benutzer eine Schaltfläche auf einem Controller drückt, kann es etwa 20 Ms drahtloser Latenz über Bluetooth geben, bevor das System die Presse empfängt.
  • Wenn Sie dann eine vorwärts vorausgesagte Pose verwenden, würde es eine weitere 10-20 MS der Vorwärtsvorhersage geben, die auf die Zeit angewendet wird, zu der die Photonen des aktuellen Frames die Augen des Benutzers erreichen.

Dies bedeutet, dass Die Umfrage Ihnen eine Quell-Pose oder Kopf-Pose gibt, die 30-40 ms vorwärts ist, wo der Kopf und die Hände des Benutzers tatsächlich zurück waren, wenn die Presse oder Veröffentlichung geschehen ist. Bei HoloLens-Handeingaben gibt es zwar keine Funkübertragungsverzögerung, aber es gibt eine ähnliche Verarbeitungsverzögerung, um die Presse zu erkennen.

Um auf der Grundlage der ursprünglichen Absicht eines Benutzers für eine Hand- oder Controller-Presse genau zu zielen, sollten Sie die historische Quell-Pose oder Kopf-Pose von diesem InteractionSourcePressed- oder InteractionSourceReleased-Eingabeereignis verwenden.

Sie können eine Pressemitteilung oder Veröffentlichung mit historischen Posendaten aus dem Kopf des Benutzers oder deren Controller ausrichten:

  • Die Kopfvorschau zu dem Zeitpunkt, zu dem eine Geste oder ein Controller gedrückt wurde, der zum Ziel verwendet werden kann, um zu bestimmen, auf welche Weise der Benutzer nachschaut :

    void InteractionManager_InteractionSourcePressed(InteractionSourcePressedEventArgs args) {
         var interactionSourceState = args.state;
         var headPose = interactionSourceState.headPose;
         RaycastHit raycastHit;
         if (Physics.Raycast(headPose.position, headPose.forward, out raycastHit, 10)) {
             var targetObject = raycastHit.collider.gameObject;
             // ...
         }
    }
    
  • Die Quelle stellt sich zur Zeit dar, in der ein Bewegungscontroller gedrückt wurde, der zum Ziel verwendet werden kann, um zu bestimmen, auf welche Weise der Benutzer den Controller angibt. Dies ist der Zustand des Controllers, der die Presse erlebt hat. Wenn Sie den Controller selbst rendern, können Sie die Zeigerpose anstelle der Grip-Pose anfordern, um den Zielstrahl von dem zu drehen, was der Benutzer als natürliche Spitze des gerenderten Controllers betrachtet:

    void InteractionManager_InteractionSourcePressed(InteractionSourcePressedEventArgs args)
    {
         var interactionSourceState = args.state;
         var sourcePose = interactionSourceState.sourcePose;
         Vector3 sourceGripPosition;
         Quaternion sourceGripRotation;
         if ((sourcePose.TryGetPosition(out sourceGripPosition, InteractionSourceNode.Pointer)) &&
             (sourcePose.TryGetRotation(out sourceGripRotation, InteractionSourceNode.Pointer))) {
             RaycastHit raycastHit;
             if (Physics.Raycast(sourceGripPosition, sourceGripRotation * Vector3.forward, out raycastHit, 10)) {
                 var targetObject = raycastHit.collider.gameObject;
                 // ...
             }
         }
    }
    

Beispiel für Ereignishandler

using UnityEngine.XR.WSA.Input;

void Start()
{
    InteractionManager.InteractionSourceDetected += InteractionManager_InteractionSourceDetected;
    InteractionManager.InteractionSourceLost += InteractionManager_InteractionSourceLost;
    InteractionManager.InteractionSourcePressed += InteractionManager_InteractionSourcePressed;
    InteractionManager.InteractionSourceReleased += InteractionManager_InteractionSourceReleased;
    InteractionManager.InteractionSourceUpdated += InteractionManager_InteractionSourceUpdated;
}

void OnDestroy()
{
    InteractionManager.InteractionSourceDetected -= InteractionManager_InteractionSourceDetected;
    InteractionManager.InteractionSourceLost -= InteractionManager_InteractionSourceLost;
    InteractionManager.InteractionSourcePressed -= InteractionManager_InteractionSourcePressed;
    InteractionManager.InteractionSourceReleased -= InteractionManager_InteractionSourceReleased;
    InteractionManager.InteractionSourceUpdated -= InteractionManager_InteractionSourceUpdated;
}

void InteractionManager_InteractionSourceDetected(InteractionSourceDetectedEventArgs args)
{
    // Source was detected
    // args.state has the current state of the source including id, position, kind, etc.
}

void InteractionManager_InteractionSourceLost(InteractionSourceLostEventArgs state)
{
    // Source was lost. This will be after a SourceDetected event and no other events for this
    // source id will occur until it is Detected again
    // args.state has the current state of the source including id, position, kind, etc.
}

void InteractionManager_InteractionSourcePressed(InteractionSourcePressedEventArgs state)
{
    // Source was pressed. This will be after the source was detected and before it is
    // released or lost
    // args.state has the current state of the source including id, position, kind, etc.
}

void InteractionManager_InteractionSourceReleased(InteractionSourceReleasedEventArgs state)
{
    // Source was released. The source would have been detected and pressed before this point.
    // This event will not fire if the source is lost
    // args.state has the current state of the source including id, position, kind, etc.
}

void InteractionManager_InteractionSourceUpdated(InteractionSourceUpdatedEventArgs state)
{
    // Source was updated. The source would have been detected before this point
    // args.state has the current state of the source including id, position, kind, etc.
}

Bewegungscontroller in MRTK

Sie können über den Eingabe-Manager auf Gesten- und Bewegungscontroller zugreifen.

Immer am Ball mit Tutorials

Schrittweise Lernprogramme mit detaillierteren Anpassungsbeispielen stehen in der Mixed Reality Academy zur Verfügung:

MR Input 213 - Bewegungscontroller
MR Input 213 - Bewegungscontroller

Nächster Entwicklungsprüfpunkt

Wenn Sie die Unity-Entwicklungsreise verfolgen, die wir eingerichtet haben, befinden Sie sich in der Mitte der Erkundung der MRTK-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.

Siehe auch