Seleção de alvos suportada pelo olho


De volta a "Eye tracking in the MixedRealityToolkit"

MRTK

Esta página discute diferentes opções para aceder a dados de olhares oculares e eventos específicos de olhar para selecionar alvos em MRTK. O rastreio de olhos permite seleções de alvos rápidas e sem esforço usando uma combinação de informações sobre o que um utilizador está a ver com entradas adicionais, tais como rastreio de mãos e comandos de voz:

  • Olhar & Diga & (comando de voz predefinido)
  • Olhe && ou "Pop" (comandos de voz personalizados)
  • Olhe & Bluetooth botão
  • Olhe & Pinch (ou seja, levante a mão na sua frente e junte o polegar e o dedo indicador)

Para selecionar conteúdo holográfico usando o olhar, existem várias opções:

1. Utilize o ponteiro de foco primário:

Isto pode ser entendido como o seu cursor prioritário. Por padrão, se as mãos estiverem à vista, então isto seriam raios de mão. Se não houver mãos à vista, então o ponteiro prioritário seria olhar de cabeça ou olho. Assim, note que, com base na cabeça de design atual ou no olhar dos olhos, é suprimida como entrada de cursor se forem utilizados raios manuais.

Por exemplo:

Um utilizador quer selecionar um botão holográfico distante. Como desenvolvedor, pretende fornecer uma solução flexível que permita ao utilizador realizar estas tarefas em várias condições:

  • Caminhe até o botão e pique-o
  • Olhe à distância e diga "selecione"
  • Direcione o botão utilizando um raio de mão e realize uma pitada Neste caso, a solução mais flexível é utilizar o manipulador de foco primário, uma vez que irá notificá-lo sempre que o ponteiro de foco primário atualmente priorizado desencadear um evento. Por favor, note que, se os raios de mão estiverem ativados, o ponteiro de foco da cabeça ou do olho fica desativado assim que as mãos entram em vista.

Importante

Por favor, note que, se os raios de mão estiverem ativados, o ponteiro de foco da cabeça ou do olho fica desativado assim que as mãos entram em vista. Se quiser suportar uma interação de "olhar e beliscar", tem de desativar o raio de mão. Nas nossas cenas de amostra de rastreio de olhos, desativamos o raio de mão para permitir a apresentação de interações mais ricas usando movimentos de olhos + movimentos de mão - veja-se, por exemplo, posicionamento apoiado pelos olhos.

2. Utilize simultaneamente o foco ocular e os raios de mão:

Pode haver casos em que você quer ser mais específico que tipo de ponteiros de foco pode desencadear certos eventos e permitir simultaneamente usar várias técnicas de interação distante.

Por exemplo: Na sua aplicação, um utilizador pode usar raios de mão distantes para manipular alguma configuração mecânica holográfica - por exemplo, agarrar e segurar algumas peças distantes do motor holográfico e mantê-los no lugar. Ao fazê-lo, o utilizador tem de analisar uma série de instruções e registar o seu progresso marcando algumas caixas de verificação. Se o utilizador não tiver as mãos ocupadas,seria instintivo simplesmente tocar na caixa de verificação ou selecioná-la com um raio de mão. No entanto, se o utilizador tiver as mãos ocupadas, como no nosso caso, segurando algumas peças do motor holográfico no lugar, pretender que o utilizador percorra perfeitamente as instruções utilizando o seu olhar e basta olhar para uma caixa de verificação e dizer "verifique!".

Para ativar isto, precisa de utilizar um script eyeTrackingTarget específico para os olhos, independente do núcleo MRTK FocusHandlers e será discutido mais abaixo.

1. Utilize o foco genérico e os manipuladores de ponteiros

Se o rastreio dos olhos for configurado corretamente (ver configuração Básica mrtk para usar o rastreio dos olhos), permitir que os utilizadores selecionem hologramas usando os seus olhos é o mesmo que para qualquer outra entrada de foco (por exemplo, olhar para a cabeça ou raio de mão). Isto proporciona a grande vantagem de uma forma flexível de interagir com os hologramas, definindo o tipo de focagem principal no seu Perfil de Ponteiro de Entrada MRTK, dependendo das necessidades do seu utilizador, deixando o seu código intocado. Isto permite alternar entre a cabeça ou o olhar ocular sem alterar uma linha de código ou substituir os raios de mão por alvos oculares para interações longíncais.

Focando-se num holograma

Para detetar quando um holograma está focado, utilize a interface 'IMixedRealityFocusHandler' que lhe fornece dois membros de interface: OnFocusEnter e OnFocusExit.

Aqui está um exemplo simples do ColorTap.cs para mudar a cor de um holograma quando é olhado.

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler
{
    void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
    {
        material.color = color_OnHover;
    }

    void IMixedRealityFocusHandler.OnFocusExit(FocusEventData eventData)
    {
        material.color = color_IdleState;
    }
    ...
}

Selecionando um holograma focado

Para selecionar um holograma focado, utilize o PointerHandler para ouvir eventos de entrada para confirmar uma seleção. Por exemplo, adicionar o IMixedRealityPointerHandler irá fazê-los reagir a uma simples entrada de ponteiro. A interface IMixedRealityPointerHandler requer a implementação dos seguintes três membros de interface: OnPointerUp,OnPointerDowne OnPointerClicked.

No exemplo abaixo, mudamos a cor de um holograma olhando para ele e beliscando ou dizendo "selecione". A ação necessária para desencadear o evento é definida pelo eventData.MixedRealityInputAction == selectAction qual podemos definir o tipo de selectAction in the Unitity Editor - por padrão é a ação "Select". Os tipos de MixedRealityInputActions disponíveis podem ser configurados no perfil MRTK através do perfil de configuração MRTK - Entrada - Ações de entrada.

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler
{
    // Allow for editing the type of select action in the Unity Editor.
    [SerializeField]
    private MixedRealityInputAction selectAction = MixedRealityInputAction.None;
    ...

    void IMixedRealityPointerHandler.OnPointerUp(MixedRealityPointerEventData eventData)
    {
        if (eventData.MixedRealityInputAction == selectAction)
        {
            material.color = color_OnHover;
        }
    }

    void IMixedRealityPointerHandler.OnPointerDown(MixedRealityPointerEventData eventData)
    {
        if (eventData.MixedRealityInputAction == selectAction)
        {
            material.color = color_OnSelect;
        }
    }

    void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData) { }
}

BaseEyeFocusHandler específico do olhar dos olhos

Dado que o olhar dos olhos pode ser muito diferente de outras entradas de ponteiro, você pode querer ter certeza de apenas reagir à entrada de foco se for olhar para os olhos e é atualmente o ponteiro de entrada primária. Para o efeito, utilizaria o BaseEyeFocusHandler que é específico para o rastreio dos olhos e que deriva do BaseFocusHandler . Como mencionado anteriormente, só disparará se o alvo do olhar dos olhos for atualmente a entrada primária do ponteiro (isto é, nenhum raio manual está ativo). Para mais informações, consulte Como apoiar o olhar + gestos com as mãos.

Aqui está um exemplo de EyeTrackingDemo-03-Navigation (Ativos/MRTK/Exemplos/Demos/EyeTracking/Scenes). Nesta demonstração, existem dois hologramas 3D que irão girar dependendo da parte do objeto que é analisada: Se o utilizador olhar para o lado esquerdo do holograma, então essa parte irá lentamente mover-se para a frente virada para o utilizador. Se o lado direito for olhado, então essa parte irá lentamente para a frente. Este é um comportamento que você pode não querer ter ativo em todos os momentos e também algo que você pode não querer acidentalmente desencadear por um raio de mão ou olhar de cabeça. Tendo o OnLookAtRotateByEyeGaze anexado, um GameObject rodará enquanto é observado.

public class OnLookAtRotateByEyeGaze : BaseEyeFocusHandler
{
    ...

    protected override void OnEyeFocusStay()
    {
        // Update target rotation
        RotateHitTarget();
    }

    ...

    ///
    /// This function computes the rotation of the target to move the currently
    /// looked at aspect slowly to the front.
    ///
    private void RotateHitTarget()
    {
        // Example for querying the hit position of the eye gaze ray using EyeGazeProvider
        Vector3 TargetToHit = (this.gameObject.transform.position - InputSystem.EyeGazeProvider.HitPosition).normalized;

        ...
    }
}

Consulte a documentação da API para obter uma lista completa dos eventos disponíveis BaseEyeFocusHandler do :

  • OnEyeFocusStart: Desencadeado assim que o raio do olhar começa a cruzar-se com o colisor deste alvo.
  • OnEyeFocusSta: Desencadeado enquanto o raio do olhar dos olhos está a cruzar-se com o colisor deste alvo.
  • OnEyeFocusstop: Desencadeado assim que o raio do olhar para de se cruzar com o colisor deste alvo.
  • OnEyeFocusDwell: Desencadeado uma vez que o raio do olhar dos olhos se cruzou com o colisor deste alvo por um período de tempo especificado.

2. EyeTrackingTarget específico de olhar independente

Finalmente, fornecemos-lhe uma solução que permite tratar a entrada baseada nos olhos completamente independente de outros ponteiros de foco através do EyeTrackingTarget script.

Isto tem três vantagens:

  • Pode certificar-se de que o holograma está apenas a reagir ao olhar do utilizador.
  • Isto é independente da entrada primária atualmente ativa. Assim, você pode processar várias entradas ao mesmo tempo - por exemplo, combinando alvos rápidos com gestos de mão.
  • Vários eventos de Unidade já foram criados para tornar rápido e conveniente lidar e reutilizar comportamentos existentes dentro do Editor de Unidade ou via código.

Há também algumas desvantagens:

  • Mais esforço para lidar com entradas separadas individualmente.
  • Sem degradação elegante: Só suporta o alvo ocular. Se o rastreio dos olhos não estiver a funcionar, precisa de algum recuo adicional.

Semelhante ao BaseFocusHandler,o EyeTrackingTarget vem pronto com vários eventos de unidade específicos para olhar para os olhos que pode ouvir convenientemente através do Editor de Unidade (ver exemplo abaixo) ou usando AddListener() em código:

  • OnLookAtStart()
  • WhileLookingAtTarget()
  • OnLookAway()
  • OnDwell()
  • OnSelected()

No seguinte, passamos por alguns exemplos para como usar o EyeTrackingTarget.

Exemplo #1: Notificações inteligentes suportadas pelo olho

Em EyeTrackingDemo-02-TargetSelection (Ativos/MRTK/Exemplos/Demos/EyeTracking/Scenes), pode encontrar um exemplo para EyeTrackingDemo-02-TargetSelection que reagem ao seu olhar. Estas são caixas de texto 3D que podem ser colocadas na cena e que irão suavemente ampliar e virar para o utilizador quando são olhadas para facilitar a legibilidade. Enquanto o utilizador está a ler a notificação, as informações continuam a ser apresentadas crisp e claras. Depois de a ler e olhar para o lado da notificação, a notificação será automaticamente descartada e desaparece. Para conseguir tudo isto, existem alguns scripts genéricos de comportamento que não são específicos para rastrear os olhos, tais como:

A vantagem desta abordagem é que os mesmos scripts podem ser reutilizados por vários eventos. Por exemplo, um holograma pode começar a ser virado para o utilizador com base num comando de voz ou depois de premir um botão virtual. Para desencadear estes eventos, pode simplesmente referenciar os métodos que devem ser executados no EyeTrackingTarget script que está ligado ao seu GameObject.

Por exemplo, as "notificações inteligentes e atentas",acontece o seguinte:

  • OnLookAtStart(): A notificação começa a...

    • FaceUser.Engage: ... virar para o utilizador.
    • ChangeSize.Engage: ... aumento do tamanho (até uma escala máxima especificada).
    • BlendOut.Engage: ... começa a misturar-se mais (depois de estar em um estado mais subtil de ocioso).
  • OnDwell(): Informa o script BlendOut de que a notificação foi examinada suficientemente.

  • OnLookAway(): A notificação começa a...

    • FaceUser.Desengatar: ... voltar para a sua orientação original.
    • ChangeSize.Desengatar: ... diminuir de volta ao seu tamanho original.
    • BlendOut.Disengage: ... começa a misturar-se - Se o OnDwell foi acionado, misture completamente e destrua, caso contrário de volta ao seu estado ocioso.

Consideração do projeto: A chave para uma experiência agradável aqui é afinar cuidadosamente a velocidade de qualquer um destes comportamentos para evitar causar desconforto, reagindo ao olhar do utilizador muito rapidamente. Caso contrário, isto pode rapidamente parecer extremamente avassalador.

Notificação-alvo

Exemplo #2: A gema holográfica gira lentamente ao olhar para ela

À semelhança do Exemplo #1, podemos facilmente criar um feedback sobre hover para as nossas joias holográficas na EyeTrackingDemo-02-TargetSelection cena (Ativos/MRTK/Exemplos/Demos/EyeTracking/Scenes) que irá rodar lentamente numa direção constante e a uma velocidade constante (em contraste com o exemplo de rotação de cima) quando ser olhada. Tudo o que precisa é desencadear a rotação da gema holográfica do evento WhileLookingAtTarget do EyeTrackingTarget.. Aqui estão mais alguns detalhes:

  1. Crie um script genérico que inclua uma função pública para rodar o GameObject a que está ligado. Abaixo está um exemplo da RotateWithConstSpeedDir.cs onde podemos ajustar a direção de rotação e velocidade do Editor de Unidade.

    using UnityEngine;
    
    namespace Microsoft.MixedReality.Toolkit.Examples.Demos.EyeTracking
    {
        /// <summary>
        /// The associated GameObject will rotate when RotateTarget() is called based on a given direction and speed.
        /// </summary>
        public class RotateWithConstSpeedDir : MonoBehaviour
        {
            [Tooltip("Euler angles by which the object should be rotated by.")]
            [SerializeField]
            private Vector3 RotateByEulerAngles = Vector3.zero;
    
            [Tooltip("Rotation speed factor.")]
            [SerializeField]
            private float speed = 1f;
    
            /// <summary>
            /// Rotate game object based on specified rotation speed and Euler angles.
            /// </summary>
            public void RotateTarget()
            {
                transform.eulerAngles = transform.eulerAngles + RotateByEulerAngles * speed;
            }
        }
    }
    
  2. Adicione o EyeTrackingTarget script ao seu GameObject alvo e refira a função EyeTrackingTarget gatilho UnityEvent como mostra a imagem abaixo:

    Amostra eyeTrackingTarget

Exemplo #3: Pop essas joias aka multimodal olho-olhar-olhar-olhar seleção alvo

No exemplo anterior, mostrámos como é fácil detetar se um alvo é analisado e como desencadear uma reação a isso. Em seguida, vamos fazer as joias explodir usando o evento OnSelected() do . A parte interessante é como a seleção é desencadeada. O EyeTrackingTarget permite atribuir rapidamente diferentes formas de invocar uma seleção:

  • Gesto de beliscar: Configurar a 'Ação selecionada' para 'Selecionar' utiliza o gesto de mão predefinido para ativar a seleção. Isto significa que o utilizador pode simplesmente levantar a mão e beliscar o polegar e o dedo indicador juntos para confirmar a seleção.

  • Diga "Selecione": Utilize o comando de voz predefinido "Select" para selecionar um holograma.

  • Diga "Explodir" ou "Pop":Para utilizar comandos de voz personalizados, tem de seguir dois passos:

    1. Configurar uma ação personalizada como "DestroyTarget"

      • Navegar para MRTK - Input - Input > Actions
      • Clique em "Adicionar uma nova ação"
    2. Configurar os comandos de voz que desencadeiam esta ação como "Explodir" ou "Pop"

      • Navegar para MRTK - Entrada - > Discurso
      • Clique em "Adicionar um novo comando de fala"
        • Associe a ação que acabou de criar
        • Atribua um KeyCode para permitir desencadear a ação através de uma pressão de botão

Voz comanda amostra EyeTrackingTarget

Quando uma joia é selecionada, explodirá, fazendo um som e desaparecendo. Isto é tratado pelo HitBehaviorDestroyOnSelect guião. Tem duas opções:

  • No Editor de Unidade: Você poderia simplesmente ligar o script que está ligado a cada um dos nossos modelos de gema ao evento OnSelected() Unidade no Editor de Unidade.
  • Em código: Se não quiseres arrastar e largar gameObjects, também podes simplesmente adicionar um ouvinte de eventos diretamente ao teu script.
    Aqui está um exemplo de como o fizemos no HitBehaviorDestroyOnSelect guião:
/// <summary>
/// Destroys the game object when selected and optionally plays a sound or animation when destroyed.
/// </summary>
[RequireComponent(typeof(EyeTrackingTarget))] // This helps to ensure that the EyeTrackingTarget is attached
public class HitBehaviorDestroyOnSelect : MonoBehaviour
{
    ...
    private EyeTrackingTarget myEyeTrackingTarget = null;

    private void Start()
    {
        myEyeTrackingTarget = this.GetComponent<EyeTrackingTarget>();

        if (myEyeTrackingTarget != null)
        {
            myEyeTrackingTarget.OnSelected.AddListener(TargetSelected);
        }
    }

    ...

    ///
    /// This is called once the EyeTrackingTarget detected a selection.
    ///
    public void TargetSelected()
    {
        // Play some animation
        // Play some audio effect
        // Handle destroying the target appropriately
    }
}

Exemplo #4: Use raios de mão e entrada de olhar juntos

Os raios de mão têm prioridade sobre a mira da cabeça e dos olhos. Isto significa que, se os raios de mão estiverem ativados, no momento em que as mãos forem vistas, o raio de mão funcionará como o ponteiro primário. No entanto, pode haver situações em que pretende usar raios manuais enquanto ainda deteta se um utilizador está a olhar para um determinado holograma. É fácil! Essencialmente, é necessário dois passos:

1. Ative o raio de mão: Para ativar o raio de mão, vá ao Mixed Reality Toolkit - Entrada - Ponteiros. No EyeTrackingDemo-00-RootScene onde o Kit de Ferramentas de Realidade Mista é configurado uma vez para todas as cenas de demonstração de rastreio de olhos, você deve ver o EyeTrackingDemoPointerProfile. Pode criar um novo perfil de entrada a partir do zero ou adaptar o atual rastreio de olhos:

  • Do zero: No separador Pontiades, selecione o DefaultMixedRealityInputPointerProfile do menu de contexto. Este é o perfil de ponteiro padrão que já tem o raio de mão ativado! Para alterar o cursor padrão (um ponto branco opaco), basta clonar o perfil e criar o seu próprio perfil de ponteiro personalizado. Em seguida, substitua o DefaultCursorpor EyeGazeCursor no Gaze Cursor Prefab.
  • Com base no EyeTrackingDemoPointerProfileexistente : Clique duas vezes no EyeTrackingDemoPointerProfile e adicione a seguinte entrada nas Opções de Ponte:
    • Tipo controlador: 'Mão Articulada', 'Windows Mixed Reality'
    • Destro: Qualquer
    • Pré-fabricado do ponteiro: DefaultControllerPointer

2. Detete que um holograma é analisado: Utilize o script para permitir a deteção de que um holograma é visto como descrito acima. Você também pode dar uma olhada no script da FollowEyeGaze amostra para inspiração, uma vez que este está mostrando um holograma seguindo o seu olhar (por exemplo, um cursor) se os raios de mão estão ativados ou não.

Agora, quando começares as cenas de demonstração de rastreio de olhos, devias ver um raio a sair das tuas mãos. Por exemplo, na demonstração de seleção do alvo de rastreio de olhos, o círculo semi-transparente continua a seguir o seu olhar e as joias respondem se são ou não olhadas, enquanto os botões do menu de cena superior usam o ponteiro de entrada principal (suas mãos) em vez disso.