Compartir a través de


Introducción a Solver: MRTK2

Solver Main

Los solucionadores son componentes que facilitan los medios para calcular la posición de un objeto & orientación según un algoritmo predefinido. Un ejemplo puede ser colocar un objeto en la superficie que el raycast de mirada del usuario alcanza actualmente.

Además, el sistema Solver define de forma determinista un orden de operaciones para estos cálculos de transformación, ya que no hay ninguna manera confiable de especificar en Unity el orden de actualización de los componentes.

Los solucionadores ofrecen una serie de comportamientos para adjuntar objetos a otros objetos o sistemas. Otro ejemplo sería un objeto de etiqueta que mantiene el puntero delante del usuario (en función de la cámara). Un solucionador también se podría adjuntar a un controlador y a un objeto para convertir la etiqueta de objeto en el controlador. Todos los solucionadores se pueden apilar de forma segura, por ejemplo, un comportamiento de etiquetado + magnetismo de superficie + impulso.

Uso de un solucionador

El sistema Solver consta de tres categorías de scripts:

  • Solver: clase abstracta base de la que derivan todos los solucionadores. Proporciona seguimiento de estado, parámetros de suavizado e implementación, integración automática del sistema de solucionador y orden de actualización.
  • SolverHandler: establece el objeto de referencia con el que realizar un seguimiento (por ejemplo, la transformación principal de la cámara, el rayo de mano, etc.), controla la recopilación de componentes del solucionador y los ejecuta actualizando en el orden adecuado.

La tercera categoría es el solucionador en sí. Los solucionadores siguientes proporcionan los bloques de creación para el comportamiento básico:

  • Orbital: se bloquea en una posición especificada y se desplaza desde el objeto al que se hace referencia.
  • ConstantViewSize: se escala para mantener un tamaño constante con respecto a la vista del objeto al que se hace referencia.
  • RadialView: mantiene el objeto dentro de un cono de vista convertido por el objeto al que se hace referencia.
  • Follow: mantiene el objeto dentro de un conjunto de límites definidos por el usuario del objeto al que se hace referencia.
  • InBetween: mantiene un objeto entre dos objetos de los que se realiza el seguimiento.
  • SurfaceMagnetism: convierte los rayos en superficies del mundo y alinea el objeto con esa superficie.
  • DirectionalIndicator: determina la posición y orientación de un objeto como indicador direccional. Desde el punto de referencia del destino con seguimiento SolverHandler, este indicador se orientará hacia el DirectionalTarget proporcionado.
  • Momentum: aplica aceleración, velocidad y fricción para simular el impulso y la springiness de un objeto que mueven otros solucionadores o componentes.
  • HandConstraint: restringe el objeto para seguir las manos en una región que no interseca gameobject con las manos. Útil para contenido interactivo restringido a mano, como menús, etc. Este solucionador está pensado para trabajar con IMixedRealityHand , pero también funciona con IMixedRealityController.
  • HandConstraintPalmUp: se deriva de HandConstraint, pero incluye lógica para probar si la palma de la palma está orientada al usuario antes de la activación. Este solucionador solo funciona con controladores IMixedRealityHand , con otros tipos de controlador que este solucionador se comportará igual que su clase base.

Para usar el sistema Solver, basta con agregar uno de los componentes enumerados anteriormente a un GameObject. Dado que todos los solucionadores requieren un SolverHandler, Unity creará uno automáticamente.

Nota:

Puede encontrar ejemplos de cómo usar el sistema Solvers en el archivo SolverExamples.scene .

Referencia de cómo cambiar el seguimiento

La propiedad Tipo de destino con seguimiento del SolverHandler componente define el punto de referencia que usarán todos los solucionadores para calcular sus algoritmos. Por ejemplo, un tipo de valor de Head con un componente simple SurfaceMagnetism dará como resultado un raycast desde la cabeza y en la dirección de la mirada del usuario para resolver qué superficie se alcanza. Los valores potenciales de la TrackedTargetType propiedad son:

  • Cabeza : el punto de referencia es la transformación de la cámara principal
  • ControllerRay: el punto de referencia es la LinePointer transformación en un controlador (es decir, el origen del puntero en un controlador de movimiento o controlador de mano) que apunta en la dirección del rayo de línea.
    • Use la TrackedHandedness propiedad para seleccionar la preferencia de entrega (es decir, Izquierda, Derecha, Ambos)
  • HandJoint: El punto de referencia es la transformación de una articulación manual específica
    • Use la TrackedHandedness propiedad para seleccionar la preferencia de entrega (es decir, Izquierda, Derecha, Ambos)
    • Use la TrackedHandJoint propiedad para determinar la transformación conjunta que se va a utilizar.
  • CustomOverride: punto de referencia del objeto asignado TransformOverride

Nota:

Para los tipos ControllerRay y HandJoint , el controlador del solucionador intentará proporcionar primero la transformación de controlador o mano izquierda y, a continuación, la derecha si el primero no está disponible o a menos que la TrackedHandedness propiedad especifique lo contrario.

Ejemplo de objeto de seguimiento de Solverde varias propiedades asociadas a cada TrackedTargetType

Importante

La mayoría de los solucionadores usan el vector de avance del destino de transformación de seguimiento proporcionado por .SolverHandler Cuando se usa un tipo de destino con seguimiento de la articulación de la mano, el vector hacia delante de la articulación de la palma puede apuntar a través de los dedos y no a través de la palma de la mano. Esto depende de la plataforma que suministra los datos de la articulación manual. Para la simulación de entrada y Windows Mixed Reality, es el vector ascendente el que apunta hacia arriba a través de la palma de la mano (es decir, el vector verde está hacia arriba, el vector azul es hacia delante).

Vector de reenvío

Para superar esto, actualice la propiedad Rotación adicional en a SolverHandler<90, 0, 0>. Esto garantizará que el vector hacia delante proporcionado a los solucionadores apunte a través de la palma de la mano y hacia fuera de la mano.

Rotación adicional

Como alternativa, use el tipo de destino de seguimiento de Controller Ray para obtener un comportamiento similar para apuntar con las manos.

Cómo encadenar solucionadores

Es posible agregar varios Solver componentes al mismo GameObject encadenando así sus algoritmos. Los SolverHandler componentes controlan la actualización de todos los solucionadores en el mismo GameObject. De forma predeterminada, las SolverHandler llamadas GetComponents<Solver>() en Inicio devolverán los solucionadores en el orden en que aparecen en el inspector.

Además, si establece la propiedad Transformación vinculada actualizada en true, se indicará que guarde su posición calculada, orientación, & escala a una variable intermedia a la que Solver puedan acceder todos los solucionadores (es decir GoalPosition, ). Cuando es false, Solver actualizará directamente la transformación de GameObject. Al guardar las propiedades de transformación en una ubicación intermedia, otros solucionadores pueden realizar sus cálculos a partir de la variable intermedia. Esto se debe a que Unity no permite que las actualizaciones de gameObject.transform se apilen dentro del mismo marco.

Nota:

Los desarrolladores pueden modificar el orden de ejecución de Solvers estableciendo la SolverHandler.Solvers propiedad directamente.

Cómo crear un solucionador

Todos los solucionadores deben heredar de la clase base abstracta, Solver. Los requisitos principales de una extensión solver implica reemplazar el SolverUpdate método . En este método, los desarrolladores deben actualizar las propiedades heredadas GoalPositiony GoalRotationGoalScale a los valores deseados. Además, por lo general es útil aprovechar SolverHandler.TransformTarget como marco de referencia deseado por el consumidor.

El código proporcionado a continuación proporciona un ejemplo de un nuevo componente de Solver llamado InFront que coloca el objeto adjunto 2m delante de SolverHandler.TransformTarget. Si el consumidor Headestablece como SolverHandler.TrackedTargetType , será la SolverHandler.TransformTarget transformación de cámara y, por tanto, este Solucionador colocará el GameObject 2m adjunto delante de la mirada de los usuarios en cada fotograma.

/// <summary>
/// InFront solver positions an object 2m in front of the tracked transform target
/// </summary>
public class InFront : Solver
{
    ...

    public override void SolverUpdate()
    {
        if (SolverHandler != null && SolverHandler.TransformTarget != null)
        {
            var target = SolverHandler.TransformTarget;
            GoalPosition = target.position + target.forward * 2.0f;
        }
    }
}

Guías de implementación de Solver

Propiedades comunes del solucionador

Cada componente de Solver tiene un conjunto de propiedades idénticas que controlan el comportamiento principal de Solver.

Si el suavizado está habilitado, solver actualizará gradualmente la transformación de GameObject a lo largo del tiempo a los valores calculados. La velocidad de este cambio viene determinada por la propiedad LerpTime de cada componente de transformación. Por ejemplo, un valor de MoveLerpTime más alto dará lugar a incrementos más lentos en el movimiento entre fotogramas.

Si MaintainScale está habilitado, solver usará la escala local predeterminada de GameObject.

Propiedades principales de Solver
Propiedades comunes heredadas por todos los componentes de Solver

Orbital

La Orbital clase es un componente de etiqueta que se comporta como planetas en un sistema solar. Este Solucionador garantizará que la gameobject adjunta orbita alrededor de la transformación de seguimiento. Por lo tanto, si el tipo de destino con seguimiento de SolverHandler está establecido en Head, gameobject orbitará alrededor de la cabeza del usuario con un desplazamiento fijo aplicado.

Los desarrolladores pueden modificar este desplazamiento fijo para mantener los menús u otros componentes de la escena a nivel de ojo o en el nivel de cintura, etc. alrededor de un usuario. Para ello, modifique las propiedades Desplazamiento local y Desplazamiento global . La propiedad Tipo de orientación determina la rotación aplicada al objeto si debe mantener su rotación original o enfrentarse siempre a la cámara o la cara de cualquier transformación que esté impulsando su posición, etc.

Ejemplo orbital
Ejemplo orbital

RadialView

RadialView es otro componente de etiqueta que mantiene una parte determinada de un Objeto GameObject dentro del frustum de la vista del usuario.

Las propiedades Min & Max View Degrees determinan el tamaño de una parte del Objeto GameObject siempre debe estar en la vista.

Las propiedades Min & Max Distance determinan hasta qué punto se debe mantener GameObject del usuario. Por ejemplo, si se dirige al GameObject con una distancia mínima de 1 m, se alejará gameobject para asegurarse de que nunca esté más cerca de 1 m para el usuario.

Por lo general, RadialView se usa junto con el tipo de destino con seguimiento establecido en para Head que el componente siga la mirada del usuario. Sin embargo, este componente puede funcionar para mantenerse en "vista" de cualquier tipo de destino con seguimiento.

Ejemplo de RadialView
Ejemplo de RadialView

Follow

La Follow clase coloca un elemento delante del del destino al que se realiza el seguimiento en relación con su eje delantero local. El elemento se puede restringir de forma flexible (es decir, etiqueta a lo largo) para que no siga hasta que el destino al que se realiza el seguimiento se mueva más allá de los límites definidos por el usuario.

Funciona de forma similar al solucionador RadialView, con controles adicionales para administrar el máximo horizontal & grados de vista vertical y mecanismos para modificar la orientación del objeto.

Seguir las propiedades
Seguir las propiedades

Seguir la escena de ejemplo
Seguir escena de ejemplo (Assets/MRTK/Examples/Demos/Solvers/Scenes/FollowSolverExample.unity)

InBetween

La InBetween clase mantendrá el objeto GameObject adjunto entre dos transformaciones. Estos dos puntos de conexión de transformación se definen mediante el propio SolverHandlertipo de destino con seguimiento de GameObject y la InBetween propiedad Second Tracked Target Type del componente. Por lo general, ambos tipos se establecerán en CustomOverride y los valores resultantes SolverHandler.TransformOverride y InBetween.SecondTransformOverride se establecerán en los dos puntos de conexión de los que se realiza el seguimiento.

En tiempo de ejecución, el InBetween componente creará otro SolverHandler componente basado en las propiedades Second Tracked Target Type (Tipo de destino de segundo seguimiento) y Second Transform Override (Invalidación de segunda transformación ).

define PartwayOffset dónde a lo largo de la línea entre dos transformaciones el objeto se colocará con 0,5 como mitad, 1,0 en la primera transformación y 0,0 en la segunda transformación.

Ejemplo de InBetween
Ejemplo de uso del solucionador InBetween para mantener el objeto entre dos transformaciones

SurfaceMagnetism

Funciona SurfaceMagnetism mediante la realización de un raycast contra un conjunto LayerMask de superficies y colocando el GameObject en ese punto de contacto.

Surface Normal Offset colocará gameobject a una distancia establecida en metros de distancia de la superficie en la dirección de lo normal en el punto de acierto de la superficie.

Por el contrario, surface ray offset colocará el GameObject una distancia establecida en metros de distancia de la superficie, pero en la dirección opuesta de la difusión de rayos realizada. Por lo tanto, si el raycast es la mirada del usuario, GameObject se acercará a lo largo de la línea desde el punto de acierto de la superficie hasta la cámara.

El Modo de orientación determina el tipo de rotación que se va a aplicar en relación con lo normal en la superficie.

  • Ninguno : no se aplica ninguna rotación
  • TrackedTarget : el objeto se enfrentará a la transformación de seguimiento que impulsa el raycast
  • SurfaceNormal : el objeto se alineará en función de lo normal en el punto de acierto de la superficie.
  • Mezclado: el objeto se alineará en función de lo normal en el punto de acierto de la superficie Y en función de la transformación con seguimiento.

Para forzar que el objeto GameObject asociado permanezca vertical en cualquier modo que no sea Ninguno, habilite Mantener la orientación vertical.

Nota:

Utilice la propiedad Combinación de orientación para controlar el equilibrio entre los factores de rotación cuando modo de orientación se establece en Blended. Un valor de 0,0 tendrá una orientación totalmente controlada por el modo TrackedTarget y un valor de 1,0 tendrá una orientación controlada completamente por SurfaceNormal.

Ejemplo de SurfaceMagnetism

Determinar qué superficies se pueden alcanzar

Al agregar un SurfaceMagnetism componente a un Objeto GameObject, es importante tener en cuenta la capa de GameObject y sus elementos secundarios, si hay colisionadores. El componente funciona realizando varios tipos de raycasts para determinar con qué superficie se va a "imán". Si el solucionador GameObject tiene un colisionador en una de las capas enumeradas en la MagneticSurfaces propiedad de SurfaceMagnetism, es probable que el raycast se alcance a sí mismo, lo que provocará que GameObject se adjunte a su propio punto colisionador. Este comportamiento impar se puede evitar estableciendo el GameObject principal y todos los elementos secundarios en la capa Ignore Raycast o modificando la MagneticSurfaces matriz LayerMask adecuadamente.

Por el contrario, un SurfaceMagnetism Objeto GameObject no colisionará con las superficies de una capa que no aparece en la MagneticSurfaces propiedad . Por lo general, se recomienda colocar todas las superficies deseadas en una capa dedicada (es decir , Superficies) y establecer la MagneticSurfaces propiedad en solo esta capa. Usar el valor predeterminado o todo puede dar lugar a que los componentes o cursores de la interfaz de usuario contribuyan al solucionador.

Por último, los raycasts omitirán las superficies más allá del MaxRaycastDistance valor de propiedad SurfaceMagnetism .

DirectionalIndicator

La DirectionalIndicator clase es un componente de etiqueta que se orienta hacia la dirección de un punto deseado en el espacio.

Se usa más comúnmente cuando el tipo de destino con seguimiento de SolverHandler se establece en Head. De esta manera, un componente de experiencia de usuario con el DirectionalIndicator solucionador dirigirá a un usuario a examinar el punto deseado en el espacio.

El punto deseado en el espacio se determina a través de la propiedad Target direccional .

Si el usuario puede ver el destino direccional o cualquier marco de referencia establecido en , SolverHandlereste solucionador deshabilitará todos los Renderer componentes que se encuentran debajo de él. Si no se puede ver, todo se habilitará en el indicador.

El tamaño del indicador se reducirá cuanto más cerca esté el usuario de capturar el destino direccional en su FOV.

  • Escala mínima del indicador : escala mínima para el objeto de indicador

  • Escala máxima del indicador : escala máxima para el objeto del indicador

  • Factor de escala de visibilidad : multiplicador para aumentar o disminuir el FOV que determina si el punto de destino direccional es visible o no.

  • Desplazamiento de vista: desde el punto de vista del marco de referencia (es decir, la cámara posiblemente), esta propiedad define la distancia en la dirección del indicador si el objeto debe estar desde el centro de la ventanilla.

Propiedades del indicador direccional
Propiedades del indicador direccional

Escena de ejemplo de indicador direccional
Escena de ejemplo de indicador direccional (Assets/MRTK/Examples/Demos/Solvers/Scenes/DirectionalIndicatorSolverExample.unity)

Menú de mano con HandConstraint y HandConstraintPalmUp

Ejemplo de experiencia de usuario del menú de mano

El HandConstraint comportamiento proporciona un solucionador que restringe el objeto de seguimiento a una región segura para el contenido restringido a mano (como la interfaz de usuario de la mano, los menús, etc.). Las regiones seguras se consideran áreas que no intersecan con la mano. También se incluye una clase derivada de HandConstraint llamada HandConstraintPalmUp para mostrar un comportamiento común de activación del objeto de seguimiento del solucionador cuando la palma de la mano se encuentra frente al usuario.

Consulte la página Menú de mano para ver los ejemplos de uso del solucionador de restricciones de mano para crear menús a mano.

Vea también