Sélection cible prise en charge des yeux — MRTK2
Cette page présente différentes options pour accéder aux données du regard et aux événements spécifiques du regard pour sélectionner des cibles dans MRTK. Le suivi oculaire permet des sélections de cibles rapides et sans effort à l’aide d’une combinaison d’informations sur ce qu’un utilisateur regarde avec des entrées supplémentaires telles que le suivi de la main et les commandes vocales :
- Look & Say « Select » (commande vocale par défaut)
- Regardez & Dire « Exploser » ou « Pop » (commandes vocales personnalisées)
- Regarder & bouton Bluetooth
- Regardez & Pincement (c’est-à-dire, tenez votre main devant vous et apportez votre pouce et votre index ensemble)
- Veuillez noter que pour que cela fonctionne, les rayons de la main doivent être désactivés
Pour sélectionner du contenu holographique à l’aide du regard, il existe plusieurs options :
1. Utilisez le pointeur de focus principal :
Cela peut être compris comme votre curseur prioritaire. Par défaut, si les mains sont visibles, il s’agit de rayons de la main. Si aucune main n’est visible, le pointeur prioritaire est la tête ou le regard. Par conséquent, notez que, en fonction de la tête de conception actuelle ou du regard, le regard est supprimé en tant qu’entrée de curseur si des rayons de la main sont utilisés.
Par exemple :
Un utilisateur souhaite sélectionner un bouton holographique distant. En tant que développeur, vous souhaitez fournir une solution flexible qui permet à l’utilisateur d’effectuer ces tâches dans différentes conditions :
- Marchez jusqu’au bouton et piquez-le
- Regardez-le à distance et dites « sélectionner »
- Cibler le bouton à l’aide d’un rayon de main et effectuer un pincement Dans ce cas, la solution la plus flexible consiste à utiliser le gestionnaire de focus principal, car il vous avertira chaque fois que le pointeur de focus principal actuellement prioritaire déclenche un événement. Notez que si les rayons de la main sont activés, le pointeur de focus de la tête ou du regard est désactivé dès que les mains sont visibles.
Important
Notez que si les rayons de la main sont activés, le pointeur de focus de la tête ou du regard est désactivé dès que les mains sont visibles. Si vous souhaitez prendre en charge une interaction « regarder et pincer », vous devez désactiver le rayon de la main. Dans nos exemples de scènes de suivi oculaire, nous avons désactivé le rayon de la main pour permettre de présenter des interactions plus riches à l’aide des yeux et des mouvements de la main ( voir par exemple Positionnement oculaire pris en charge).
2. Utilisez à la fois les rayons du focus oculaire et de la main en même temps :
Il peut y avoir des instances où vous souhaitez être plus précis sur le type de pointeurs de focus pouvant déclencher certains événements et permettre l’utilisation simultanée de plusieurs techniques d’interaction à distance.
Par exemple : dans votre application, un utilisateur peut utiliser des rayons de loin pour manipuler une configuration mécanique holographique, par exemple, saisir et maintenir certaines parties du moteur holographique distantes et les maintenir en place. Ce faisant, l’utilisateur doit suivre un certain nombre d’instructions et enregistrer sa progression en marquant certaines zones case activée. Si l’utilisateur n’a pas les mains occupées, il serait instinctif de simplement toucher la zone case activée ou de la sélectionner à l’aide d’un rayon de main. Toutefois, si l’utilisateur a les mains occupées, comme dans notre cas en tenant certaines parties du moteur holographique en place, vous souhaitez permettre à l’utilisateur de parcourir en toute transparence les instructions à l’aide de son regard et de simplement regarder une boîte de case activée et de dire « case activée ! ».
Pour cela, vous devez utiliser un script EyeTrackingTarget spécifique à l’œil qui est indépendant des focusHandlers MRTK de base et qui sera abordé plus en détail ci-dessous.
Si le suivi oculaire est correctement configuré (voir Configuration MRTK de base pour utiliser le suivi oculaire), permettre aux utilisateurs de sélectionner des hologrammes à l’aide de leurs yeux est le même que pour toute autre entrée de focus (par exemple, le regard de la tête ou la main). Cela offre le grand avantage d’une façon flexible d’interagir avec vos hologrammes en définissant le main type de focus dans votre profil de pointeur d’entrée MRTK en fonction des besoins de votre utilisateur, tout en laissant votre code intact. Cela permet de basculer entre la tête ou le regard sans modifier une ligne de code ou remplacer les rayons des mains par le ciblage oculaire pour les interactions éloignées.
Pour détecter quand un hologramme est ciblé, utilisez l’interface « IMixedRealityFocusHandler » qui vous fournit deux membres d’interface : OnFocusEnter et OnFocusExit.
Voici un exemple simple de ColorTap.cs pour modifier la couleur d’un hologramme lors d’un regard.
public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler
{
void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
{
material.color = color_OnHover;
}
void IMixedRealityFocusHandler.OnFocusExit(FocusEventData eventData)
{
material.color = color_IdleState;
}
...
}
Pour sélectionner un hologramme ciblé, utilisez PointerHandler pour écouter les événements d’entrée et confirmer une sélection. Par exemple, l’ajout de IMixedRealityPointerHandler les fera réagir à une entrée de pointeur simple. L’interface IMixedRealityPointerHandler nécessite l’implémentation des trois membres d’interface suivants : OnPointerUp, OnPointerDown et OnPointerClicked.
Dans l’exemple ci-dessous, nous changeons la couleur d’un hologramme en le regardant et en le pinçant ou en disant « sélectionner ».
L’action requise pour déclencher l’événement est définie en eventData.MixedRealityInputAction == selectAction
définissant le type de selectAction
dans l’éditeur Unity . Par défaut, il s’agit de l’action « Sélectionner ». Les types de MixedRealityInputActions disponibles peuvent être configurés dans le profil MRTK via le profil de configuration MRTK ->Input ->Input Actions.
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) { }
}
Étant donné que le regard peut être très différent des autres entrées de pointeur, vous pouvez vous assurer de ne réagir à l’entrée focus que s’il s’agit d’un regard visuel et qu’il s’agit actuellement du pointeur d’entrée principal.
À cette fin, vous utiliserez le BaseEyeFocusHandler
qui est spécifique au suivi oculaire et qui dérive de .BaseFocusHandler
Comme mentionné précédemment, il se déclenche uniquement si le ciblage du regard est actuellement l’entrée principale du pointeur (c’est-à-dire qu’aucun rayon de main n’est actif). Pour plus d’informations, consultez Comment prendre en charge les mouvements du regard et de la main.
Voici un exemple de EyeTrackingDemo-03-Navigation
(Assets/MRTK/Examples/Demos/EyeTracking/Scenes).
Dans cette démonstration, il existe deux hologrammes 3D qui s’activent en fonction de la partie de l’objet examinée : si l’utilisateur regarde le côté gauche de l’hologramme, cette partie se déplace lentement vers l’avant de l’utilisateur.
Si le côté droit est regardé, cette partie se déplacera lentement vers l’avant.
Il s’agit d’un comportement que vous ne voulez peut-être pas avoir actif en tout temps et aussi quelque chose que vous ne voudrez peut-être pas déclencher accidentellement par un rayon de main ou un regard de tête.
Avec l’élément OnLookAtRotateByEyeGaze
attaché, un GameObject pivote pendant qu’il est examiné.
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;
...
}
}
Consultez la documentation de l’API pour obtenir la liste complète des événements disponibles du BaseEyeFocusHandler
:
- OnEyeFocusStart : Déclenché une fois que le rayon du regard commence à croiser avec le collisionneur de cette cible.
- OnEyeFocusStay : Déclenché alors que le rayon du regard se croise avec le collisionneur de cette cible.
- OnEyeFocusStop : Déclenché une fois que le rayon du regard cesse d’être croisé avec le collisionneur de cette cible.
- OnEyeFocusDwell : Déclenché une fois que le rayon du regard a croisé le collisionneur de cette cible pendant une durée spécifiée.
Enfin, nous vous fournissons une solution qui vous permet de traiter les entrées basées sur les yeux complètement indépendantes des autres pointeurs de focus via le EyeTrackingTarget
script.
Cela présente trois avantages :
- Vous pouvez vous assurer que l’hologramme réagit uniquement au regard de l’utilisateur.
- Elle est indépendante de l’entrée principale actuellement active. Par conséquent, vous pouvez traiter plusieurs entrées à la fois, par exemple, en combinant le ciblage rapide des yeux avec les mouvements de la main.
- Plusieurs événements Unity ont déjà été configurés pour faciliter la gestion et la réutilisation des comportements existants à partir de l’éditeur Unity ou via le code.
Il existe également certains inconvénients :
- Plus d’efforts pour gérer des entrées distinctes individuellement.
- Pas de dégradation élégante : il prend uniquement en charge le ciblage oculaire. Si le suivi oculaire ne fonctionne pas, vous avez besoin d’une solution de secours supplémentaire.
Semblable à BaseFocusHandler, l’EyeTrackingTarget est fourni avec plusieurs événements Unity spécifiques aux yeux que vous pouvez facilement écouter via l’éditeur Unity (voir l’exemple ci-dessous) ou en utilisant AddListener() dans le code :
- OnLookAtStart()
- WhileLookingAtTarget()
- OnLookAway()
- OnDwell()
- OnSelected()
Dans ce qui suit, nous vous guiderons à travers quelques exemples d’utilisation d’EyeTrackingTarget.
Dans EyeTrackingDemo-02-TargetSelection
(Assets/MRTK/Examples/Demos/EyeTracking/Scenes), vous pouvez trouver un exemple de « notifications attentives intelligentes » qui réagissent à votre regard.
Il s’agit de zones de texte 3D qui peuvent être placées dans la scène et qui s’agrandissent et se tournent vers l’utilisateur en douceur lorsqu’ils sont regardés pour faciliter la lisibilité. Pendant que l’utilisateur lit la notification, les informations continuent d’être affichées nettes et claires. Après l’avoir lu et regardé loin de la notification, la notification est automatiquement ignorée et disparaît. Pour ce faire, il existe quelques scripts de comportement génériques qui ne sont pas spécifiques au suivi oculaire, tels que :
L’avantage de cette approche est que les mêmes scripts peuvent être réutilisés par différents événements. Par exemple, un hologramme peut commencer à faire face à l’utilisateur en fonction d’une commande vocale ou après avoir appuyé sur un bouton virtuel. Pour déclencher ces événements, vous pouvez simplement référencer les méthodes qui doivent être exécutées dans le EyeTrackingTarget
script attaché à votre GameObject.
Pour l’exemple de « notifications attentives intelligentes », les opérations suivantes se produisent :
OnLookAtStart() : la notification commence à...
- FaceUser.Engage : ... se tourner vers l’utilisateur.
- ChangeSize.Engage : ... augmentation de la taille (jusqu’à une échelle maximale spécifiée).
- BlendOut.Engage : ... commence à se fondre davantage (après avoir été à un état d’inactivité plus subtil) .
OnDwell() : informe le script BlendOut que la notification a été suffisamment examinée.
OnLookAway() : la notification commence à...
- FaceUser.Désengage : ... revenez à son orientation d’origine.
- ChangeSize.Désengage : ... revenir à sa taille d’origine.
- BlendOut.Désengagement : ... commence à fusionner : si OnDwell() a été déclenché, fusionnez complètement et détruisez, sinon revenez à son état inactif.
Considérations relatives à la conception : La clé d’une expérience agréable ici est d’ajuster soigneusement la vitesse de l’un de ces comportements pour éviter de causer de l’inconfort en réagissant au regard de l’utilisateur trop rapidement tout le temps. Sinon, cela peut rapidement sembler extrêmement écrasant.
À l’instar de l’exemple n° 1, nous pouvons facilement créer un retour de pointage pour nos gemmes holographiques dans EyeTrackingDemo-02-TargetSelection
la scène (Assets/MRTK/Examples/Demos/EyeTracking/Scenes) qui pivote lentement dans une direction constante et à une vitesse constante (contrairement à l’exemple de rotation ci-dessus) lors de l’analyse. Il vous suffit de déclencher la rotation de la gemme holographique à partir de l’événement WhileLookingAtTarget()d’EyeTrackingTarget. Voici quelques informations supplémentaires :
Créez un script générique qui inclut une fonction publique pour faire pivoter le GameObject auquel elle est attachée. Vous trouverez ci-dessous un exemple de RotateWithConstSpeedDir.cs dans lequel nous pouvons ajuster le sens de rotation et la vitesse à partir de l’éditeur Unity.
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; } } }
Ajoutez le
EyeTrackingTarget
script à votre GameObject cible et référencez la fonction RotateTarget() dans le déclencheur UnityEvent, comme illustré dans la capture d’écran ci-dessous :
Exemple n°3 : Faire apparaître ces gemmes ou sélection de cibles multimodaux prises en charge par les yeux
Dans l’exemple précédent, nous avons montré à quel point il est facile de détecter si une cible est examinée et comment déclencher une réaction à cela. Ensuite, nous allons faire exploser les gemmes à l’aide de l’événement OnSelected() de .EyeTrackingTarget
La partie intéressante est la façon dont la sélection est déclenchée. permet EyeTrackingTarget
d’attribuer rapidement différentes façons d’appeler une sélection :
Mouvement de pincement : la définition de l’action « Sélectionner » sur « Sélectionner » utilise le mouvement de la main par défaut pour déclencher la sélection. Cela signifie que l’utilisateur peut simplement lever sa main et pincer son pouce et son index ensemble pour confirmer la sélection.
Dites « Sélectionner » : utilisez la commande vocale par défaut « Select » pour sélectionner un hologramme.
Dites « Exploser » ou « Pop » : pour utiliser des commandes vocales personnalisées, vous devez suivre deux étapes :
Configurer une action personnalisée telle que « DestroyTarget »
- Accédez à MRTK -> Entrée -> Actions d’entrée
- Cliquez sur « Ajouter une nouvelle action »
Configurer les commandes vocales qui déclenchent cette action, telles que « Exploser » ou « Pop »
- Accédez à MRTK -> Entrée -> Voix
- Cliquez sur « Ajouter une nouvelle commande vocale »
- Associer l’action que vous venez de créer
- Affecter un code clé pour autoriser le déclenchement de l’action via une pression sur un bouton
Quand une gemme est sélectionnée, elle explose, fait un son et disparaît. Cela est géré par le HitBehaviorDestroyOnSelect
script. Deux options s'offrent à vous :
- Dans l’éditeur Unity : Vous pouvez simplement lier le script attaché à chacun de nos modèles de gemmes à l’événement Unity OnSelected() dans l’éditeur Unity.
-
Dans le code : Si vous ne souhaitez pas glisser-déplacer des GameObjects, vous pouvez également simplement ajouter un écouteur d’événement directement à votre script.
Voici un exemple de la façon dont nous l’avons fait dans leHitBehaviorDestroyOnSelect
script :
/// <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
}
}
Les rayons des mains sont prioritaires sur le ciblage du regard et de la tête. Cela signifie que, si les rayons de la main sont activés, au moment où les mains entrent en vue, le rayon de la main agit comme pointeur principal. Toutefois, il peut y avoir des situations dans lesquelles vous souhaitez utiliser des rayons de la main tout en détectant si un utilisateur regarde un certain hologramme. Facile ! Essentiellement, vous avez besoin de deux étapes :
1. Activer le rayon de la main : pour activer le rayon de la main, accédez à Mixed Reality Kit de ressources -> Entrée -> Pointeurs. Dans EyeTrackingDemo-00-RootScene où Mixed Reality Toolkit est configuré une fois pour toutes les scènes de démonstration de suivi oculaire, vous devez voir eyeTrackingDemoPointerProfile. Vous pouvez créer un profil d’entrée à partir de zéro ou adapter le suivi oculaire actuel :
- À partir de zéro : Sous l’onglet Pointeurs , sélectionnez defaultMixedRealityInputPointerProfile dans le menu contextuel. Il s’agit du profil de pointeur par défaut sur lequel le rayon de main est déjà activé ! Pour modifier le curseur par défaut (point blanc opaque), clonez simplement le profil et créez votre propre profil de pointeur personnalisé. Remplacez ensuite DefaultCursor parEyeGazeCursor sous Le prefab du curseur de regard.
-
En fonction de l’EyeTrackingDemoPointerProfile existant : double-cliquez sur eyeTrackingDemoPointerProfile et ajoutez l’entrée suivante sous Options du pointeur :
- Type de contrôleur : 'Main articulée', 'Windows Mixed Reality'
- La main : Tout
- Prefab pointeur : DefaultControllerPointer
2. Détecter qu’un hologramme est examiné : utilisez le EyeTrackingTarget
script pour permettre de détecter qu’un hologramme est examiné comme décrit ci-dessus. Vous pouvez également jeter un coup d’œil à l’exemple FollowEyeGaze
de script pour vous inspirer, car il montre un hologramme suivant votre regard (par exemple, un curseur) si les rayons de main sont activés ou non.
Maintenant, lorsque vous commencez les scènes de démonstration de suivi oculaire, vous devriez voir un rayon provenant de vos mains. Par exemple, dans la démonstration de sélection de la cible de suivi oculaire, le cercle semi-transparent suit toujours votre regard et les gemmes répondent à leur regard ou non, tandis que les boutons de menu de la scène supérieure utilisent le pointeur d’entrée principal (vos mains) à la place.