Controladores de movimiento en UnityMotion controllers in Unity

Hay dos formas clave de tomar medidas en su mirada en Unity, gestos de mano y controladores de movimiento en HoloLens y HMDs envolventes.There are two key ways to take action on your gaze in Unity, hand gestures and motion controllers in HoloLens and Immersive HMD. Puede tener acceso a los datos de los dos orígenes de entrada espacial a través de las mismas API en Unity.You access the data for both sources of spatial input through the same APIs in Unity.

Unity proporciona dos maneras principales de tener acceso a los datos de entrada espacial para Windows Mixed Reality.Unity provides two primary ways to access spatial input data for Windows Mixed Reality. Las API de Input. GetButton/Input. GetAxis comunes funcionan en varios SDK de Unity XR, mientras que la API InteractionManager/GestureRecognizer específica de Windows Mixed Reality expone el conjunto completo de datos de entrada espacial.The common Input.GetButton/Input.GetAxis APIs work across multiple Unity XR SDKs, while the InteractionManager/GestureRecognizer API specific to Windows Mixed Reality exposes the full set of spatial input data.

API de entrada de Unity XRUnity XR input APIs

En el caso de los proyectos nuevos, se recomienda usar las nuevas API de entrada de XR desde el principio.For new projects, we recommend using the new XR input APIs from the beginning.

Puede encontrar más información sobre las API de XR aquí.You can find more information about the XR APIs here.

Tabla de asignación de ejes y botones de UnityUnity button/axis mapping table

El administrador de entrada de Unity para los controladores de movimiento de Windows Mixed Reality es compatible con los identificadores de botón y de eje que se enumeran a continuación a través de las API Input. GetButton/GetAxis .Unity's Input Manager for Windows Mixed Reality motion controllers supports the button and axis IDs listed below through the Input.GetButton/GetAxis APIs. La columna "específico de Windows MR" hace referencia a las propiedades disponibles fuera del tipo InteractionSourceState .The "Windows MR-specific" column refers to properties available off of the InteractionSourceState type. Cada una de estas API se describe en detalle en las secciones siguientes.Each of these APIs is described in detail in the sections below.

Las asignaciones de identificador de botón/eje para Windows Mixed Reality suelen coincidir con los identificadores del botón o del eje Oculus.The button/axis ID mappings for Windows Mixed Reality generally match the Oculus button/axis IDs.

Las asignaciones de identificador de botón/eje para Windows Mixed Reality difieren de las asignaciones de OpenVR de dos maneras:The button/axis ID mappings for Windows Mixed Reality differ from OpenVR's mappings in two ways:

  1. La asignación usa identificadores de Touchpad distintos del stick analógico para admitir controladores con thumbsticks y Touchpad.The mapping uses touchpad IDs that are distinct from thumbstick, to support controllers with both thumbsticks and touchpads.
  2. La asignación evita la sobrecarga de los identificadores de botón A y X de los botones de menú para dejarlos a disposición de los botones de ABXY físicos.The mapping avoids overloading the A and X button IDs for the Menu buttons to leave them available for the physical ABXY buttons.
EntradaInput API comunes de UnityCommon Unity APIs
(Input. GetButton/GetAxis)(Input.GetButton/GetAxis)
API de entrada específica de Windows MRWindows MR-specific Input API
XR. WSA. Entradas(XR.WSA.Input)
Mano izquierdaLeft hand Mano derechaRight hand
Seleccionar desencadenador presionadoSelect trigger pressed Eje 9 = 1,0Axis 9 = 1.0 Eje 10 = 1,0Axis 10 = 1.0 selectPressedselectPressed
Seleccionar desencadenador de valor analógicoSelect trigger analog value Eje 9Axis 9 Eje 10Axis 10 selectPressedAmountselectPressedAmount
Seleccionar desencadenador parcialmente presionadoSelect trigger partially pressed Botón 14 (compatibilidad con el controlador de juegos) Button 14 (gamepad compat) Botón 15 (compatibilidad con el controlador de juegos) Button 15 (gamepad compat) selectPressedAmount > 0,0selectPressedAmount > 0.0
Botón de menú presionadoMenu button pressed Botón 6 \*Button 6\* Botón 7 \*Button 7\* menuPressedmenuPressed
Botón de control presionadoGrip button pressed Eje 11 = 1,0 (sin valores analógicos)Axis 11 = 1.0 (no analog values)
Botón 4 (compatibilidad con el controlador de juegos) Button 4 (gamepad compat)
Eje 12 = 1,0 (sin valores analógicos)Axis 12 = 1.0 (no analog values)
Botón 5 (compatibilidad con el controlador de juegos) Button 5 (gamepad compat)
entendidograsped
Stick analógico X (izquierda:-1,0, derecha: 1,0) Thumbstick X (left: -1.0, right: 1.0) Eje 1Axis 1 Eje 4Axis 4 thumbstickPosition. xthumbstickPosition.x
Stick analógico Y (superior:-1,0, inferior: 1,0) Thumbstick Y (top: -1.0, bottom: 1.0) Eje 2Axis 2 Eje 5Axis 5 thumbstickPosition. ythumbstickPosition.y
Stick analógico presionadoThumbstick pressed Botón 8Button 8 Botón 9Button 9 thumbstickPressedthumbstickPressed
Touchpad X (izquierda:-1,0, derecha: 1,0) Touchpad X (left: -1.0, right: 1.0) Eje 17 \*Axis 17\* Eje 19 \*Axis 19\* touchpadPosition. xtouchpadPosition.x
Touchpad Y (superior:-1,0, inferior: 1,0) Touchpad Y (top: -1.0, bottom: 1.0) Eje 18 \*Axis 18\* Eje 20 \*Axis 20\* touchpadPosition. ytouchpadPosition.y
Touchpad tocadoTouchpad touched Botón 18 \*Button 18\* Botón 19 \*Button 19\* touchpadTouchedtouchpadTouched
Touchpad presionadoTouchpad pressed Botón 16 \*Button 16\* Botón 17 \*Button 17\* touchpadPressedtouchpadPressed
replanteamiento de control de 6DoF o de puntero6DoF grip pose or pointer pose El puño solo representa: XR. InputTracking. GetLocalPositionGrip pose only: XR.InputTracking.GetLocalPosition
XR. InputTracking.GetLocalRotationXR.InputTracking.GetLocalRotation
Pase el control o el puntero como argumento: SourceState. sourcePose. TryGetPositionPass Grip or Pointer as an argument: sourceState.sourcePose.TryGetPosition
sourceState.sourcePose.TryGetRotationsourceState.sourcePose.TryGetRotation
Estado de seguimientoTracking state Riesgo de pérdida y precisión de la posición solo disponible a través de la API específica de MR Position accuracy and source loss risk only available through MR-specific API sourceState.sourcePose.positionAccuracysourceState.sourcePose.positionAccuracy
sourceState. properties. sourceLossRisksourceState.properties.sourceLossRisk

Nota

Estos ID. de botón o eje difieren de los identificadores que usa Unity para OpenVR debido a colisiones en las asignaciones que usan los controladores de juegos, Oculus Touch y OpenVR.These button/axis IDs differ from the IDs that Unity uses for OpenVR due to collisions in the mappings used by gamepads, Oculus Touch and OpenVR.

Replanteamiento de control frente a pose de punteroGrip pose vs. pointing pose

Windows Mixed Reality admite controladores de movimiento en diversos factores de forma.Windows Mixed Reality supports motion controllers in a variety of form factors. El diseño de cada controlador difiere en su relación entre la posición del usuario y la dirección de "avance" natural que las aplicaciones deben usar para apuntar al representar el controlador.Each controller's design differs in its relationship between the user's hand position and the natural "forward" direction that apps should use for pointing when rendering the controller.

Para representar mejor estos controladores, hay dos tipos de supuestos que puede investigar para cada origen de interacción, la representación del control y la representación del puntero.To better represent these controllers, there are two kinds of poses you can investigate for each interaction source, the grip pose and the pointer pose. Las coordenadas de reposición de control y de posición de puntero se expresan en todas las API de Unity en coordenadas globales de Unity.Both the grip pose and pointer pose coordinates are expressed by all Unity APIs in global Unity world coordinates.

Replanteamiento de controlGrip pose

El puño representa la ubicación de la palma de los usuarios, detectada por HoloLens o manteniendo un controlador de movimiento.The grip pose represents the location of the users palm, either detected by a HoloLens or holding a motion controller.

En los auriculares envolventes, la representación del puño es la que mejor se usa para representar la mano del usuario o un objeto mantenido en la mano del usuario.On immersive headsets, the grip pose is best used to render the user's hand or an object held in the user's hand. El replanteamiento de control también se usa al visualizar un controlador de movimiento.The grip pose is also used when visualizing a motion controller. El modelo representable proporcionado por Windows para un controlador de movimiento utiliza la representación del puño como su origen y centro de rotación.The renderable model provided by Windows for a motion controller uses the grip pose as its origin and center of rotation.

La pose de control se define específicamente de la siguiente manera:The grip pose is defined specifically as follows:

  • La posición del puño: Palm centroide cuando mantiene el controlador de forma natural, se ajusta hacia la izquierda o derecha para centrar la posición dentro del control.The grip position: The palm centroid when holding the controller naturally, adjusted left or right to center the position within the grip. En el controlador de movimiento de Windows Mixed Reality, esta posición generalmente se alinea con el botón de agarre.On the Windows Mixed Reality motion controller, this position generally aligns with the Grasp button.
  • Eje derecho de la orientación del puño: cuando se abre por completo la mano para formar una postura plana de 5 dedos, el rayo perpendicular a la palma (hacia delante de la mano izquierda y hacia atrás desde la mano derecha)The grip orientation's Right axis: When you completely open your hand to form a flat 5-finger pose, the ray that is normal to your palm (forward from left palm, backward from right palm)
  • El eje hacia delante de la orientación del puño: al cerrar la mano (como si contiene el controlador), el rayo que señala "reenviar" a través del tubo formado por los dedos no Thumb.The grip orientation's Forward axis: When you close your hand partially (as if holding the controller), the ray that points "forward" through the tube formed by your non-thumb fingers.
  • Eje hacia arriba de la orientación del puño: el eje hacia arriba implícito por las definiciones derecha y hacia delante.The grip orientation's Up axis: The Up axis implied by the Right and Forward definitions.

Puede acceder a la representación del puño a través de la API de entrada entre proveedores (XR) de Unity . InputTracking. GetLocalPosition/Rotation) o a través de la API específica de Windows Mr (SourceState. SourcePose. TryGetPosition/Rotation, que solicita los datos de pose para el nodo de control ).You can access the grip pose through either Unity's cross-vendor input API (XR.InputTracking.GetLocalPosition/Rotation) or through the Windows MR-specific API (sourceState.sourcePose.TryGetPosition/Rotation, requesting pose data for the Grip node).

Representar punteroPointer pose

La pose de puntero representa la punta del controlador que señala hacia delante.The pointer pose represents the tip of the controller pointing forward.

La representación de puntero proporcionada por el sistema se usa mejor para Raycast cuando se representa el propio modelo de controlador.The system-provided pointer pose is best used to raycast when you're rendering the controller model itself. Si está representando algún otro objeto virtual en lugar del controlador, como un cañón virtual, debe apuntar con un rayo que sea más natural para ese objeto virtual, como un rayo que viaja a lo largo del barril del modelo de pistola definido por la aplicación.If you're rendering some other virtual object in place of the controller, such as a virtual gun, you should point with a ray that's most natural for that virtual object, such as a ray that travels along the barrel of the app-defined gun model. Dado que los usuarios pueden ver el objeto virtual y no el controlador físico, es probable que apunte con el objeto virtual sea más natural para los que usan su aplicación.Because users can see the virtual object and not the physical controller, pointing with the virtual object will likely be more natural for those using your app.

Actualmente, la pose de puntero solo está disponible en Unity a través de la API específica de Windows MR, sourceState. sourcePose. TryGetPosition/Rotation, pasando InteractionSourceNode. Pointer como argumento.Currently, the pointer pose is available in Unity only through the Windows MR-specific API, sourceState.sourcePose.TryGetPosition/Rotation, passing in InteractionSourceNode.Pointer as the argument.

Estado de seguimiento del controladorController tracking state

Al igual que los auriculares, el controlador de movimiento de Windows Mixed Reality no requiere la configuración de sensores de seguimiento externos.Like the headsets, the Windows Mixed Reality motion controller requires no setup of external tracking sensors. En su lugar, el seguimiento de los controladores se realiza mediante sensores en el propio casco.Instead, the controllers are tracked by sensors in the headset itself.

Si el usuario mueve los controladores fuera del campo de vista del casco, Windows continúa inferencia de las posiciones del controlador en la mayoría de los casos.If the user moves the controllers out of the headset's field of view, Windows continues to infer controller positions in most cases. Cuando el controlador ha perdido el seguimiento visual durante el tiempo suficiente, las posiciones del controlador se quitarán de las posiciones de precisión aproximada.When the controller has lost visual tracking for long enough, the controller's positions will drop to approximate-accuracy positions.

En este punto, el sistema bloqueará el controlador al usuario, realizará un seguimiento de la posición del usuario a medida que se mueven, mientras se expone la verdadera orientación del controlador mediante sus sensores de orientación internos.At this point, the system will body-lock the controller to the user, tracking the user's position as they move around, while still exposing the controller's true orientation using its internal orientation sensors. Muchas aplicaciones que usan Controladores para apuntar a los elementos de la interfaz de usuario y activarlos pueden funcionar con normalidad mientras tienen una precisión aproximada sin que el usuario lo note.Many apps that use controllers to point at and activate UI elements can operate normally while in approximate accuracy without the user noticing.

La mejor manera de hacerse una idea es probarlo.The best way to get a feel for this is to try it yourself. Consulte este vídeo con ejemplos de contenido envolvente que funciona con controladores de movimiento en varios Estados de seguimiento:Check out this video with examples of immersive content that works with motion controllers across various tracking states:


Razonamiento sobre el estado de seguimiento explícitamenteReasoning about tracking state explicitly

Las aplicaciones que quieren tratar las posiciones de manera diferente según el estado de seguimiento pueden ir más allá e inspeccionar las propiedades en el estado del controlador, como SourceLossRisk y PositionAccuracy:Apps that wish to treat positions differently based on tracking state may go further and inspect properties on the controller's state, such as SourceLossRisk and PositionAccuracy:

Estado de seguimientoTracking state SourceLossRiskSourceLossRisk PositionAccuracyPositionAccuracy TryGetPositionTryGetPosition
Alta precisión High accuracy < 1,0< 1.0 AltoHigh truetrue
Alta precisión (riesgo de pérdida) High accuracy (at risk of losing) = = 1,0== 1.0 AltoHigh truetrue
Precisión aproximada Approximate accuracy = = 1,0== 1.0 AproximadoApproximate truetrue
Ninguna posición No position = = 1,0== 1.0 AproximadoApproximate falsefalse

Estos Estados de seguimiento del controlador de movimiento se definen de la siguiente manera:These motion controller tracking states are defined as follows:

  • Alta precisión: Aunque el controlador de movimiento está en el campo de vista del casco, normalmente proporcionará posiciones de alta precisión en función del seguimiento visual.High accuracy: While the motion controller is within the headset's field of view, it will generally provide high-accuracy positions, based on visual tracking. Un controlador de movimiento que deja momentáneamente el campo de vista o que se oculta momentáneamente de los sensores de auriculares (por ejemplo, por la otra mano del usuario) seguirá devolviendo resultados de alta precisión durante un breve período de tiempo, en función del seguimiento inerte del propio controlador.A moving controller that momentarily leaves the field of view or is momentarily obscured from the headset sensors (e.g. by the user's other hand) will continue to return high-accuracy poses for a short time, based on inertial tracking of the controller itself.
  • Alta precisión (riesgo de pérdida): Cuando el usuario mueve el controlador de movimiento más allá del borde del campo de vista del casco, el casco pronto no podrá realizar un seguimiento visual de la posición del controlador.High accuracy (at risk of losing): When the user moves the motion controller past the edge of the headset's field of view, the headset will soon be unable to visually track the controller's position. La aplicación sabe cuándo el controlador ha alcanzado este límite de hiperapartados; para ello, vea el SourceLossRisk Reach 1,0.The app knows when the controller has reached this FOV boundary by seeing the SourceLossRisk reach 1.0. En ese momento, la aplicación puede optar por pausar los gestos del controlador que requieren un flujo estable de planteamientos de alta calidad.At that point, the app may choose to pause controller gestures that require a steady stream of high quality poses.
  • Precisión aproximada: Cuando el controlador ha perdido el seguimiento visual durante el tiempo suficiente, las posiciones del controlador se quitarán de las posiciones de precisión aproximada.Approximate accuracy: When the controller has lost visual tracking for long enough, the controller's positions will drop to approximate-accuracy positions. En este punto, el sistema bloqueará el controlador al usuario, realizará un seguimiento de la posición del usuario a medida que se mueven, mientras se expone la verdadera orientación del controlador mediante sus sensores de orientación internos.At this point, the system will body-lock the controller to the user, tracking the user's position as they move around, while still exposing the controller's true orientation using its internal orientation sensors. Muchas aplicaciones que usan Controladores para apuntar a los elementos de la interfaz de usuario y activarlos pueden funcionar de la manera normal, pero con una precisión aproximada sin que los usuarios lo noten.Many apps that use controllers to point at and activate UI elements can operate as normal while in approximate accuracy without the user noticing. Las aplicaciones con requisitos de entrada más pesados pueden optar por detectar este descenso de alta precisión a una precisión aproximada mediante la inspección de la propiedad PositionAccuracy , por ejemplo, para proporcionar al usuario una hitbox más amplia en los destinos de la pantalla durante este tiempo.Apps with heavier input requirements may choose to sense this drop from High accuracy to Approximate accuracy by inspecting the PositionAccuracy property, for example to give the user a more generous hitbox on off-screen targets during this time.
  • Ninguna posición: Aunque el controlador puede funcionar con una precisión aproximada durante mucho tiempo, a veces el sistema sabe que incluso una posición bloqueada por el cuerpo no es significativa en este momento.No position: While the controller can operate at approximate accuracy for a long time, sometimes the system knows that even a body-locked position isn't meaningful at the moment. Por ejemplo, un controlador que se ha activado puede que nunca se haya observado visualmente, o que un usuario pueda poner un controlador que recoja otro usuario.For example, a controller that was turned on may have never been observed visually, or a user may put down a controller that's then picked up by someone else. En ese momento, el sistema no proporcionará ninguna posición a la aplicación y TryGetPosition devolverá FALSE.At those times, the system won't provide any position to the app, and TryGetPosition will return false.

API de Unity comunes (Input. GetButton/GetAxis)Common Unity APIs (Input.GetButton/GetAxis)

Espacio de nombres: UnityEngine, UnityEngine. XRNamespace: UnityEngine, UnityEngine.XR
Types: Input, XR. InputTrackingTypes: Input, XR.InputTracking

Unity usa actualmente sus API de entrada general. GetButton/Input. GetAxis para exponer la entrada para el SDK de Oculus, el SDK de OpenVR y Windows Mixed Reality, incluidas las manos y los controladores de movimiento.Unity currently uses its general Input.GetButton/Input.GetAxis APIs to expose input for the Oculus SDK, the OpenVR SDK and Windows Mixed Reality, including hands and motion controllers. Si la aplicación usa estas API para la entrada, puede admitir fácilmente controladores de movimiento en varios SDK de XR, incluido Windows Mixed Reality.If your app uses these APIs for input, it can easily support motion controllers across multiple XR SDKs, including Windows Mixed Reality.

Obtener el estado presionado de un botón lógicoGetting a logical button's pressed state

Para usar las API de entrada de Unity generales, normalmente se empieza por conectar botones y ejes a nombres lógicos en el Administrador de entrada de Unity, enlazando un botón o ID. de eje a cada nombre.To use the general Unity input APIs, you'll typically start by wiring up buttons and axes to logical names in the Unity Input Manager, binding a button or axis IDs to each name. Después, puede escribir código que haga referencia a ese botón o nombre de eje lógico.You can then write code that refers to that logical button/axis name.

Por ejemplo, para asignar el botón de desencadenador del controlador de movimiento izquierdo a la acción de envío, vaya a editar > configuración del proyecto > entrada en Unity y expanda las propiedades de la sección enviar en ejes.For example, to map the left motion controller's trigger button to the Submit action, go to Edit > Project Settings > Input within Unity, and expand the properties of the Submit section under Axes. Cambie el botón positivo o la propiedad del botón positivo alternativo para leer el botón 14 del joystick, de la siguiente manera:Change the Positive Button or Alt Positive Button property to read joystick button 14, like this:

InputManager de UnityUnity's InputManager
InputManager de UnityUnity InputManager

Después, el script puede comprobar la acción de envío mediante Input. GetButton:Your script can then check for the Submit action using Input.GetButton:

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

Puede agregar más botones lógicos cambiando la propiedad tamaño en ejes.You can add more logical buttons by changing the Size property under Axes.

Obtener el estado presionado del botón físico directamenteGetting a physical button's pressed state directly

También puede tener acceso a los botones manualmente por su nombre completo, mediante Input. GetKey:You can also access buttons manually by their fully qualified name, using Input.GetKey:

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

Obtención de un controlador de movimiento o mando a manoGetting a hand or motion controller's pose

Puede tener acceso a la posición y la rotación del controlador mediante XR. InputTracking:You can access the position and rotation of the controller, using XR.InputTracking:

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

Nota

El código anterior representa la representación del puño del controlador (donde el usuario contiene el controlador), que es útil para representar un arma o un cañón en la mano del usuario, o un modelo del propio controlador.The above code represents the controller's grip pose (where the user holds the controller), which is useful for rendering a sword or gun in the user's hand, or a model of the controller itself.

La relación entre esta postura de control y el representador de puntero (donde está señalando la punta del controlador) puede diferir entre los controladores.The relationship between this grip pose and the pointer pose (where the tip of the controller is pointing) may differ across controllers. En este momento, el acceso a la pose de puntero del controlador solo es posible a través de la API de entrada específica de MR, que se describe en las secciones siguientes.At this moment, accessing the controller's pointer pose is only possible through the MR-specific input API, described in the sections below.

API específicas de Windows (XR. WSA. EntradasWindows-specific APIs (XR.WSA.Input)

Precaución

Si el proyecto usa cualquiera de las de XR. Las API de WSA, se están desinstalando en favor del SDK de XR en futuras versiones de Unity.If your project is using any of the XR.WSA APIs, these are being phased out in favor of the XR SDK in future Unity releases. En el caso de los proyectos nuevos, se recomienda usar el SDK de XR desde el principio.For new projects, we recommend using the XR SDK from the beginning. Puede encontrar más información sobre el sistema de entrada de XR y las API aquí.You can find more information about the XR Input system and APIs here.

Espacio de nombres: UnityEngine. XR. WSA. InputNamespace: UnityEngine.XR.WSA.Input
Tipos: InteractionManager, InteractionSourceState, InteractionSource, InteractionSourceProperties, InteractionSourceKind, InteractionSourceLocationTypes: InteractionManager, InteractionSourceState, InteractionSource, InteractionSourceProperties, InteractionSourceKind, InteractionSourceLocation

Para obtener información más detallada sobre la entrada de mano de Windows Mixed Reality (para HoloLens) y los controladores de movimiento, puede optar por usar las API de entrada espacial específicas de Windows en el espacio de nombres UnityEngine. XR. WSA. Input .To get at more detailed information about Windows Mixed Reality hand input (for HoloLens) and motion controllers, you can choose to use the Windows-specific spatial input APIs under the UnityEngine.XR.WSA.Input namespace. Esto le permite tener acceso a información adicional, como la precisión de la posición o el tipo de origen, lo que permite indicar a las manos y los controladores.This lets you access additional information, such as position accuracy or the source kind, letting you tell hands and controllers apart.

Sondeo del estado de los controladores de manos y de movimientoPolling for the state of hands and motion controllers

Puede sondear el estado de este fotograma para cada origen de interacción (controlador de movimiento o mano) mediante el método GetCurrentReading .You can poll for this frame's state for each interaction source (hand or motion controller) using the GetCurrentReading method.

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

Cada InteractionSourceState que recibe representa un origen de interacción en el momento actual.Each InteractionSourceState you get back represents an interaction source at the current moment in time. InteractionSourceState expone información como:The InteractionSourceState exposes info such as:

  • Qué tipos de pulsaciones se están produciendo (Select/menu/agarre/Touchpad/Stick)Which kinds of presses are occurring (Select/Menu/Grasp/Touchpad/Thumbstick)

    if (interactionSourceState.selectPressed) {
         // ...
    }
    
  • Otros datos específicos de los controladores de movimiento, tales como las coordenadas XY y/o el estado de tocado del Stick.Other data specific to motion controllers, such the touchpad and/or thumbstick's XY coordinates and touched state

    if (interactionSourceState.touchpadTouched && interactionSourceState.touchpadPosition.x > 0.5) {
         // ...
    }
    
  • InteractionSourceKind para saber si el origen es una mano o un controlador de movimientoThe InteractionSourceKind to know if the source is a hand or a motion controller

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

Sondeo de representación de representación de predicción de reenvíoPolling for forward-predicted rendering poses

  • Cuando se realiza un sondeo de los datos de origen de interacción de las manos y los controladores, las supuestos que obtiene son supuestos predichos en el momento en que las fotos de este fotograma llegarán a los ojos del usuario.When polling for interaction source data from hands and controllers, the poses you get are forward-predicted poses for the moment in time when this frame's photons will reach the user's eyes. Los planteamientos de predicción se usan mejor para representar el controlador o un objeto mantenido en cada fotograma.Forward-predicted poses are best used for rendering the controller or a held object each frame. Si el destino es una determinada pulsación o versión con el controlador, será más preciso si usa las API de eventos históricos que se describen a continuación.If you're targeting a given press or release with the controller, that will be most accurate if you use the historical event APIs described below.

    var sourcePose = interactionSourceState.sourcePose;
    Vector3 sourceGripPosition;
    Quaternion sourceGripRotation;
    if ((sourcePose.TryGetPosition(out sourceGripPosition, InteractionSourceNode.Grip)) &&
         (sourcePose.TryGetRotation(out sourceGripRotation, InteractionSourceNode.Grip))) {
         // ...
    }
    
  • También puede obtener el representa el encabezado de predicción hacia delante para este marco actual.You can also get the forward-predicted head pose for this current frame. Al igual que en el caso de la representación de origen, esto resulta útil para representar un cursor, aunque el destino de una determinada pulsación o versión será más preciso si usa las API de eventos históricos que se describen a continuación.As with the source pose, this is useful for rendering a cursor, although targeting a given press or release will be most accurate if you use the historical event APIs described below.

    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;
         // ...
    }
    

Control de eventos de origen de interacciónHandling interaction source events

Para controlar los eventos de entrada a medida que se producen con sus datos de pose históricos precisos, puede controlar los eventos de origen de interacción en lugar de realizar un sondeo.To handle input events as they happen with their accurate historical pose data, you can handle interaction source events instead of polling.

Para controlar los eventos de origen de interacción:To handle interaction source events:

  • Regístrese para un evento de entrada InteractionManager .Register for a InteractionManager input event. Para cada tipo de evento de interacción que le interese, necesita suscribirse a él.For each type of interaction event that you are interested in, you need to subscribe to it.

    InteractionManager.InteractionSourcePressed += InteractionManager_InteractionSourcePressed;
    
  • Controle el evento.Handle the event. Una vez que se haya suscrito a un evento de interacción, recibirá la devolución de llamada cuando sea necesario.Once you have subscribed to an interaction event, you will get the callback when appropriate. En el ejemplo SourcePressed , será una vez detectado el origen y antes de que se libere o se pierda.In the SourcePressed example, this will be after the source was detected and before it is released or lost.

    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
    }
    

Cómo detener el control de un eventoHow to stop handling an event

Debe dejar de controlar un evento cuando ya no le interese en el evento o si está destruyendo el objeto que se ha suscrito al evento.You need to stop handling an event when you're no longer interested in the event or you're destroying the object that has subscribed to the event. Para dejar de controlar el evento, cancele la suscripción del evento.To stop handling the event, you unsubscribe from the event.

InteractionManager.InteractionSourcePressed -= InteractionManager_InteractionSourcePressed;

Lista de eventos de origen de interacciónList of interaction source events

Los eventos de origen de interacción disponibles son:The available interaction source events are:

  • InteractionSourceDetected (el origen se activa)InteractionSourceDetected (source becomes active)
  • InteractionSourceLost (se convierte en inactivo)InteractionSourceLost (becomes inactive)
  • InteractionSourcePressed (TAP, presionar botón o "seleccionar")InteractionSourcePressed (tap, button press, or "Select" uttered)
  • InteractionSourceReleased (final de una pulsación, botón liberado o final de "Select")InteractionSourceReleased (end of a tap, button released, or end of "Select" uttered)
  • InteractionSourceUpdated (se mueve o cambia cualquier estado)InteractionSourceUpdated (moves or otherwise changes some state)

Los eventos de destinatarios históricos suponen que coinciden con más precisión con una prensa o una versiónEvents for historical targeting poses that most accurately match a press or release

Las API de sondeo descritas anteriormente proporcionan a la aplicación las supuestos predecidas.The polling APIs described earlier give your app forward-predicted poses. Aunque los planteamientos predichos son idóneos para representar el controlador o un objeto de dispositivo de mano virtual, los planteamientos futuros no son óptimos para el destino, por dos motivos clave:While those predicted poses are best for rendering the controller or a virtual handheld object, future poses aren't optimal for targeting, for two key reasons:

  • Cuando el usuario presiona un botón en un controlador, puede haber aproximadamente 20 ms de latencia inalámbrica a través de Bluetooth antes de que el sistema reciba la prensa.When the user presses a button on a controller, there can be about 20 ms of wireless latency over Bluetooth before the system receives the press.
  • A continuación, si usa una pose de predicción, se aplicará otro 10-20 ms de predicción hacia delante para dirigirse a la hora en que las fotos del fotograma actual llegarán a los ojos del usuario.Then, if you're using a forward-predicted pose, there would be another 10-20 ms of forward prediction applied to target the time when the current frame's photons will reach the user's eyes.

Esto significa que el sondeo le proporciona una pose de origen o un representador de cabeza que es 30-40 ms hacia delante desde donde el encabezado del usuario y las manecillas se han vuelto realmente cuando se produjo la prensa o la versión.This means that polling gives you a source pose or head pose that is 30-40 ms forward from where the user's head and hands actually were back when the press or release happened. Para la entrada de la mano de HoloLens, aunque no hay ningún retraso de la transmisión inalámbrica, hay un retraso de procesamiento similar para detectar la prensa.For HoloLens hand input, while there's no wireless transmission delay, there's a similar processing delay to detect the press.

Para establecer como destino con precisión en función de la intención original del usuario de una mano o de un controlador, debe usar la representación de origen histórica o la representación del encabezado de ese evento de entrada InteractionSourcePressed o InteractionSourceReleased .To accurately target based on the user's original intent for a hand or controller press, you should use the historical source pose or head pose from that InteractionSourcePressed or InteractionSourceReleased input event.

Puede tener como destino una imprenta o una versión con datos de pose históricos del encabezado del usuario o del controlador:You can target a press or release with historical pose data from the user's head or their controller:

  • El encabezado se representa en el momento en que se produjo un gesto o un pulsador del controlador, que se puede usar para determinar el destino en el que se Gazing el usuario:The head pose at the moment in time when a gesture or controller press occurred, which can be used for targeting to determine what the user was gazing at:

    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;
             // ...
         }
    }
    
  • La suposición de origen en el momento en que se produce una acción del controlador de movimiento, que se puede usar para determinar el destino del controlador.The source pose at the moment in time when a motion controller press occurred, which can be used for targeting to determine what the user was pointing the controller at. Este será el estado del controlador que experimentó la pulsación.This will be the state of the controller that experienced the press. Si está representando el propio controlador, puede solicitar la representación del puntero en lugar de la representación del control para captar el rayo de destino de lo que el usuario considerará la punta natural de ese controlador representado:If you're rendering the controller itself, you can request the pointer pose rather than the grip pose, to shoot the targeting ray from what the user will consider the natural tip of that rendered controller:

    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;
                 // ...
             }
         }
    }
    

Ejemplo de controladores de eventosEvent handlers example

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.
}

Controladores de movimiento en MRTK V2Motion Controllers in MRTK v2

Puede tener acceso al gesto y al controlador de movimiento desde el administrador de entrada.You can access gesture and motion controller from the input Manager.

Seguimiento de tutorialesFollow along with tutorials

Los tutoriales paso a paso, con ejemplos de personalización más detallados, están disponibles en la Academia de realidad mixta:Step-by-step tutorials, with more detailed customization examples, are available in the Mixed Reality Academy:

Entrada MR 213-controlador de movimientoMR Input 213 - Motion controller
Entrada MR 213-controlador de movimientoMR Input 213 - Motion controller

Siguiente punto de control de desarrolloNext Development Checkpoint

Si está siguiendo el viaje de desarrollo de Unity que hemos diseñado, está a la mitad de explorar los bloques de creación principales de MRTK.If you're following the Unity development journey we've laid out, you're in the midst of exploring the MRTK core building blocks. Desde aquí, puede continuar con el siguiente bloque de compilación:From here, you can continue to the next building block:

O bien puede saltar a las funcionalidades y las API de la plataforma de realidad mixta:Or jump to Mixed Reality platform capabilities and APIs:

Puede volver a los puntos de control de desarrollo de Unity en cualquier momento.You can always go back to the Unity development checkpoints at any time.

Consulta tambiénSee also