Freigeben über


Bewegungscontroller in Unity

Es gibt zwei wichtige Möglichkeiten, um ihre Blicke in Unity, Handgesten und Bewegungscontrollern in HoloLens und immersivem HMD zu ergreifen. Sie greifen auf die Daten für beide Quellen der räumlichen Eingabe über die gleichen APIs in Unity zu.

Unity bietet zwei primäre Möglichkeiten für den Zugriff auf räumliche Eingabedaten für Windows Mixed Reality. Die allgemeinen 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 neuen XR-Eingabe-APIs von Anfang an zu verwenden.

Weitere Informationen zu den XR-APIs finden Sie hier.

Unity-Schaltfläche/Achsenzuordnungstabelle

Der Eingabe-Manager für Windows Mixed Reality-Bewegungscontroller von Unity unterstützt die unten aufgeführten Tasten- und Achsen-IDs über die Input.GetButton/GetAxis-APIs . Die Spalte "Windows MR-specific" bezieht sich auf Eigenschaften, die aus dem 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 in der Regel den Oculus-Schaltflächen-/Achsen-IDs.

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

  1. Die Zuordnung verwendet Touchpad-IDs, die sich vom Ministick unterscheiden, um Controller mit Ministicks und 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.
Eingabe Allgemeine Unity-APIs
(Input.GetButton/GetAxis)
Windows MR-spezifische Eingabe-API
(XR. WSA. Eingabe)
Linke Rechte Hand
Auswahltrigger gedrückt Achse 9 = 1,0 Achse 10 = 1,0 selectPressed
Auslöser analogen Wert auswählen Achse 9 Achse 10 selectPressedAmount
Select trigger partially pressed Schaltfläche 14 (Gamepadkompat) Schaltfläche 15 (Gamepadkompat) 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 (Gamepadkompat)
Achse 12 = 1,0 (keine analogen Werte)
Schaltfläche 5 (Gamepadkompat)
Begriffen
Ministick X (links: -1,0, rechts: 1,0) Achse 1 Achse 4 thumbstickPosition.x
Ministick Y (oben: -1,0, unten: 1,0) Achse 2 Achse 5 thumbstickPosition.y
Ministick gedrückt Schaltfläche 8 Schaltfläche 9 MinistickPressed
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 berührt Schaltfläche 18* Schaltfläche 19* TouchpadTouched
Touchpad gedrückt Schaltfläche 16* Schaltfläche 17* touchpadPressed
6DoF Griff-Pose oder Zeiger-Pose Nur Griff posieren: 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 Tasten-/Achsen-IDs unterscheiden sich von den IDs, die Unity für OpenVR verwendet, aufgrund von Kollisionen in den Zuordnungen, die von Gamepads, Oculus Touch und OpenVR verwendet werden.

OpenXR

Informationen zu Mixed Reality-Interaktionen in Unity finden Sie im Unity-Handbuch für Unity XR-Eingaben. 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 InputFeatureUsageswie unten beschrieben zugeordnet sind:

InputFeatureUsage HP Hall G2 Controller (OpenXR) HoloLens Hand (OpenXR)
primary2DAxis Joystick
primary2DAxisClick Joystick - Klicken
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ü

Griff-Pose im Vergleich zu Zeige posieren

Windows Mixed Reality unterstützt Bewegungscontroller in einer Vielzahl von Formfaktoren. Der Entwurf jedes Controllers 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 Zeiger-Pose untersuchen können. Sowohl die Griff-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, entweder durch eine HoloLens erkannt oder einen Bewegungscontroller gehalten.

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

Die Griffpose wird speziell wie folgt definiert:

  • Die Griffposition: Das Palmzentror, wenn der Controller natürlich gehalten wird, wird links oder rechts angepasst, 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 "Erfassen".
  • Die Rechte Achse des Griffs: Wenn Sie Ihre Hand vollständig öffnen, um eine flache 5-Finger-Pose zu bilden, ist der Strahl normal für ihre Handfläche (vorwärts von der linken Handfläche, rückwärts von der rechten Handfläche)
  • Die Vorwärtsachse der Griffausrichtung: Wenn Sie Ihre Hand teilweise schließen (als wenn Sie den Controller halten), zeigt der Strahl, der durch den Röhren "vorwärts" zeigt, die durch Ihre Nichtfinger gebildet wird.
  • Die Aufwärtsachse der Griffausrichtung: Die Nach oben-Achse, die durch die Definitionen "Rechts" und "Vorwärts" impliziert wird.

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

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 Strahl zeigen, der für dieses virtuelle Objekt am natürlichsten ist, z. B. einen Strahl, der entlang des Barrels des app-definierten Waffenmodells bewegt wird. 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 benutzer, die Ihre App verwenden.

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

OpenXR

Sie haben Zugriff auf zwei Sätze von Posen über OpenXR-Eingabeinteraktionen:

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

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

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

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

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-Handbuch für Unity XR Input – Haptics.

Controllerverfolgungsstatus

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

Wenn der Benutzer die Controller aus dem Sichtfeld des Headsets verschiebt, leitet Windows die Controllerpositionen in den meisten Fällen weiter ab. Wenn der Controller lange genug visuelle Nachverfolgung verloren hat, fallen die Positionen des Controllers auf ungefähre Genauigkeitspositionen.

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, ohne dass der Benutzer darauf hinweist.

Gründe für das explizite Nachverfolgen des Status

Apps, die Positionen basierend auf dem Tracking-Zustand unterschiedlich behandeln möchten, können weiter gehen und Eigenschaften des Zustands des Controllers überprüfen, z . B. SourceLossRisk und PositionAccuracy:

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

Diese Bewegungscontrollerverfolgungszustände sind wie folgt definiert:

  • Hohe Genauigkeit: Während sich der Bewegungscontroller innerhalb des Sichtfelds des Headsets befindet, stellt er in der Regel basierend auf der visuellen Nachverfolgung hohe Genauigkeitspositionen bereit. Ein bewegungsgesteuerter Controller, der das Sichtfeld momentariell verlässt oder von den Headsetsensoren (z. B. von der anderen Hand des Benutzers) verdeckt wird, gibt weiterhin kurze Zeit hochgenaue Posen zurück, basierend auf der inertialen Nachverfolgung des Controllers selbst.
  • Hohe Genauigkeit (risikobehaftet): Wenn der Benutzer den Bewegungscontroller über den Rand des Sichtfelds des Headsets bewegt, kann das Headset die Position des Controllers bald nicht visuell verfolgen. Die App weiß, wann der Controller diese FOV-Grenze erreicht hat, indem der SourceLossRisk 1,0 erreicht hat. An diesem Punkt kann sich die App entscheiden, Controllergesten anzuhalten, die einen stetigen Stream von qualitativ hochwertigen Posen erfordern.
  • Ungefähre Genauigkeit: Wenn der Controller lange genug visuelle Nachverfolgung verloren hat, werden die Positionen des Controllers auf ungefähre Genauigkeitspositionen fallen. 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 funktionieren, ohne dass der Benutzer dies beachten muss. Apps mit schwereren Eingabeanforderungen können diesen Rückgang von hoher Genauigkeit auf ungefähre Genauigkeit erkennen, indem sie die PositionAccuracy-Eigenschaft prüfen, z. B. um dem Benutzer während dieser Zeit eine großzügigere Hitbox auf Off-Screen-Zielen zu geben.
  • Keine Position: Während der Controller lange Zeit mit ungefährer Genauigkeit arbeiten kann, weiß das System manchmal, dass selbst eine körpersperrte Position derzeit nicht aussagekräftig ist. Beispielsweise wurde ein Controller, der eingeschaltet wurde, möglicherweise nie visuell beobachtet, oder ein Benutzer kann einen Controller ablegen, der dann von einer anderen Person abgeholt 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änden und Bewegungscontrollern. Wenn Ihre App diese APIs für die Eingabe verwendet, kann sie Bewegungscontroller in mehreren XR-SDKs, einschließlich Windows Mixed Reality, problemlos unterstützen.

Abrufen des gedrückten Zustands einer logischen Schaltfläche

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

Um beispielsweise die Triggerschaltfläche des linken Bewegungscontrollers der Sendeaktion zuzuordnen, wechseln Sie zu "Projekteinstellungen > bearbeiten>" in Unity, und erweitern Sie die Eigenschaften des Abschnitts "Absenden" unter "Achsen". Ändern Sie die Eigenschaft "Positive Taste" oder "Alt Positive Schaltfläche" so, dass Sie die Joystickschaltfläche 14 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 Size-Eigenschaft unter Axes ändern.

Direktes Abrufen des gedrückten Zustands einer physischen Taste

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

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

Abrufen der Haltung eines Hand- oder Bewegungscontrollers

Mit XR können Sie 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 Griff-Pose des Controllers dar (in der der Benutzer den Controller hält), der zum Rendern eines Schwertes oder einer Waffe in der Hand des Benutzers oder eines Modells des Controllers selbst nützlich ist.

Die Beziehung zwischen dieser Griffposition und der Zeigerposition (bei der die Spitze des Controllers zeigt) kann sich zwischen controllern unterscheiden. Derzeit ist der Zugriff auf die Zeigerpose des Controllers nur über die MR-spezifische Eingabe-API möglich, die in den folgenden Abschnitten beschrieben wird.

Windows-spezifische APIs (XR. WSA. Eingabe)

Achtung

Wenn Ihr Projekt einen der XR verwendet. WSA-APIs werden zugunsten des XR-SDKs in zukünftigen Unity-Versionen abgestreckt. Für neue Projekte empfehlen wir, das XR-SDK von Anfang an zu verwenden. Weitere Informationen zum XR-Eingabesystem und zu 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 räumlichen Eingabe-APIs unter dem UnityEngine.XR.WSA.Input-Namespace verwenden. Auf diese Weise können Sie auf zusätzliche Informationen zugreifen, z. B. die Positionsgenauigkeit oder die Art der Quelle, sodass Sie Die Hände und Controller voneinander trennen können.

Abrufen des Zustands von Händen und Bewegungscontrollern

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) {
    // ...
}

Jeder InteractionSourceState , den Sie zurückholen, stellt eine Interaktionsquelle zum aktuellen Zeitpunkt dar. Der InteractionSourceState macht Informationen verfügbar, z. B.:

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

    if (interactionSourceState.selectPressed) {
         // ...
    }
    
  • Andere Für Bewegungscontroller spezifische Daten, z. B. die XY-Koordinaten des Touchpads und/oder des Ministicks und des berührten Zustands

    if (interactionSourceState.touchpadTouched && interactionSourceState.touchpadPosition.x > 0.5) {
         // ...
    }
    
  • Die InteractionSourceKind, um zu wissen, ob es sich bei der Quelle um eine Hand oder einen Bewegungscontroller handelt

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

Abfragen für forward-vorhergesagte Rendering-Posen

  • Bei der Abfrage von Interaktionsquellendaten von Händen und Controllern sind die Posen, die Sie erhalten, vorwärts vorhergesagte Posen für den Moment, in dem die Photonen dieses Frames die Augen des Benutzers erreichen. Forward-vorhergesagte Posen werden am besten zum Rendern des Controllers oder eines gehaltenen Objekts für jeden Frame verwendet. Wenn Sie auf eine bestimmte Presse oder Freigabe 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 vorwärts vorhergesagte Kopf pose für diesen aktuellen Frame erhalten. Wie bei der Quellposition ist dies hilfreich für das Rendern eines Cursors, obwohl die Ausrichtung auf eine bestimmte Presse oder Freigabe 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 während ihrer genauen historischen Posendaten zu behandeln, können Sie Interaktionsquellenereignisse behandeln, anstatt abfragen zu müssen.

So behandeln Sie Interaktionsquellenereignisse:

  • Registrieren Sie sich für ein InteractionManager-Eingabeereignis . Für jede Art von Interaktionsereignis, die Sie interessieren, 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 dem Losgelassen 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 das Objekt zerstört, das das Ereignis abonniert hat. Um die Behandlung des Ereignisses zu beenden, kündigen Sie das Ereignis ab.

InteractionManager.InteractionSourcePressed -= InteractionManager_InteractionSourcePressed;

Liste der Interaktionsquellenereignisse

Die verfügbaren Interaktionsquellenereignisse sind:

  • InteractionSourceDetected (Quelle wird aktiv)
  • InteractionSourceLost (wird inaktiv)
  • InteractionSourcePressed (Tippen, Drücken der Schaltfläche oder "Auswählen")
  • InteractionSourceReleased (Ende eines Tippens, Losgelassenen Oder Endes von "Auswählen"
  • InteractionSourceUpdated (Verschiebt oder ändert anderweitig einen Zustand)

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

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

  • Wenn der Benutzer eine Taste auf einem Controller drückt, kann es ca. 20 ms drahtlose Latenz über Bluetooth geben, bevor das System die Taste empfängt.
  • Wenn Sie dann eine vorwärts vorhergesagte Pose verwenden, würde eine weitere 10-20 ms Vorwärtsvorhersage auf die Zeit angewendet, zu der die Photonen des aktuellen Frames die Augen des Benutzers erreichen.

Dies bedeutet, dass Ihnen die Abfrage eine Quell-Pose oder Kopf-Pose gibt, die 30-40 ms vorwärts ist, von wo der Kopf und die Hände des Benutzers tatsächlich zurück waren, wenn die Presse oder Freigabe passiert ist. Bei HoloLens-Handeingaben gibt es zwar keine Verzögerung der drahtlosen Übertragung, aber es gibt eine ähnliche Verarbeitungsverzögerung, um die Taste zu erkennen.

Um basierend auf der ursprünglichen Absicht des Benutzers für ein Hand- oder Controller-Drücken genau zu zielen, sollten Sie die historische Quell-Pose oder Kopf-Pose aus diesem InteractionSourcePressed - oder InteractionSourceReleased-Eingabeereignis verwenden.

Sie können eine Presse oder Freigabe mit historischen Posendaten vom Kopf des Benutzers oder dessen Controller ausrichten:

  • Der Kopf posiert zu dem Zeitpunkt, zu dem eine Geste oder ein Controller gedrückt wurde, die für die Zielbestimmung verwendet werden kann, um zu bestimmen, was der Benutzer im Blick hatte:

    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 zu dem Zeitpunkt, zu dem ein Bewegungscontroller gedrückt wurde, dar, der zur Zielbestimmung verwendet werden kann, um zu bestimmen, auf welche Weise der Benutzer auf den Controller zeigt. Dies ist der Zustand des Controllers, der die Presse erlebt hat. Wenn Sie den Controller selbst rendern, können Sie die Zeigerposition anstelle der Griffposition anfordern, um den Zielstrahl von dem zu schießen, was der Benutzer als die natürliche Spitze dieses 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

Schritt-für-Schritt-Lernprogramme mit detaillierteren Anpassungsbeispielen sind in der Mixed Reality Academy verfügbar:

MR Input 213 - Bewegungscontroller
MR Input 213 - Bewegungscontroller

Nächster Entwicklungsprüfpunkt

Wenn Sie die Unity-Entwicklungsreise verfolgt haben, die wir eingerichtet haben, befinden Sie sich mitten in 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