Compartir a través de


Solucionadores: MRTK3

Solver Main

Los solucionadores son componentes que facilitan el cálculo de la posición y orientación de un objeto según un algoritmo predefinido. Ejemplo: colocar un objeto en la superficie con la que se interseca el raycast de mirada del usuario.

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 crear la etiqueta de objeto a lo largo del controlador. Todos los solucionadores se pueden apilar de forma segura, por ejemplo, un comportamiento de etiquetado más magnetismo de superficie y impulso.

Cómo se usa

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

  • Solver: la clase base abstracta 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 seguimiento de objetos de referencia en (por ejemplo: la transformación principal de la cámara, el rayo de mano, etc.), controla la recopilación de componentes del solucionador y ejecuta la actualización 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: objeto Constraints para seguir las manos de 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 XRNode.
  • 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 XRNode controladores y se comportará igual que su clase base con otros tipos de controladores.
  • Overlap: se superpone con el objeto al que se realiza el seguimiento.

Para usar el sistema Solver, agregue 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 una conversión de rayos 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.

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, el vector ascendente 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).

Para superar esto, actualice la propiedad Rotación adicional en a SolverHandler<90, 0, 0>. Esto garantiza 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.

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, que devolverán los solucionadores en el orden en que aparecen en el inspector.

Además, establecer la propiedad Transformación vinculada actualizada en true indicará que Solver guarde su posición calculada, orientación y escala en una variable intermedia a la que 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 intermediaria. 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 de Solver implican reemplazar el SolverUpdate método . En este método, los desarrolladores deben actualizar las propiedades heredadas GoalPosition, GoalRotationy GoalScale a los valores deseados. Además, 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 2 m delante de SolverHandler.TransformTarget. El consumidor establece SolverHandler.TrackedTargetType como Head, a continuación SolverHandler.TransformTarget , será la transformación de cámara y, por lo tanto, este Solucionador colocará el GameObject 2 m adjunto delante de la mirada de los usuarios 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 propiedad LerpTime de cada componente de transformación determina la velocidad de este cambio. 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.

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 de cintura, etc., alrededor de un usuario. Para ello, cambie 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 siempre encarar la cámara o la cara de cualquier transformación que esté impulsando su posición.

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 cuánto de una parte de GameObject debe estar siempre en vista.

Las propiedades Min & Max Distance determinan hasta qué punto se debe mantener el Objeto GameObject del usuario. Por ejemplo, si camina hacia 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 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.

Follow

La Follow clase coloca un elemento delante del destino al que se realiza el seguimiento en relación con su eje directo local. El elemento se puede restringir libremente (también conocido como "tag-along") 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 max horizontal & grados de vista vertical y mecanismos para modificar la orientación del objeto.

InBetween

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

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

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

SurfaceMagnetism

SurfaceMagnetism Funciona mediante la realización de un raycast en un conjunto LayerMask de superficies y colocando 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.

Overlap

Overlap es un solucionador simple que mantendrá la transformación del objeto en la misma posición y rotación que el destino de transformaciónSolverHandler's.

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 diversos raycasts para determinar con qué superficie se va a "imán". Supongamos que el solucionador GameObject tiene un colisionador en una de las capas enumeradas en la MagneticSurfaces propiedad de SurfaceMagnetism. En ese caso, el raycast probablemente se alcanzará a sí mismo, lo que provocará que GameObject se conecte a su propio punto de colisionador. Este comportamiento impar se puede evitar estableciendo el GameObject principal y todos los elementos secundarios en la capa de conversión Ignore Ray o modificando la MagneticSurfaces matriz LayerMask adecuadamente.

Por el contrario, un SurfaceMagnetism Objeto GameObject no colisiona con superficies de una capa que no aparece en la MagneticSurfaces propiedad . Te recomendamos que coloques todas las superficies deseadas en una capa dedicada (es decir, Superficies) y establezcas 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 del 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. Este punto viene determinado por 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 hay debajo. 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 la vista: desde el punto de vista del marco de referencia (es decir, la cámara posiblemente) y en la dirección del indicador, esta propiedad define la distancia del objeto desde el centro de la ventanilla.

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

Menú de mano con HandConstraint y HandConstraintPalmUp

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 documentación del menú mano para obtener ejemplos de cómo usar el solucionador de restricciones de mano para crear menús de mano.