Partager via


Pointeurs — MRTK2

Pointeur

Cet article explique comment configurer et répondre à l’entrée de pointeur dans la pratique. Pour mieux comprendre comment contrôler plusieurs pointeurs à un niveau élevé, consultez Architecture de pointeur.

Les pointeurs sont automatiquement instances au moment de l’exécution lorsqu’un nouveau contrôleur est détecté. Plusieurs pointeurs peuvent être attachés à un contrôleur. Par exemple, avec le profil de pointeur par défaut, Windows Mixed Reality contrôleurs obtiennent à la fois une ligne et un pointeur parabolique pour la sélection et la téléportation normales, respectivement.

Configuration du pointeur

Les pointeurs sont configurés dans le cadre du système d’entrée dans MRTK via un MixedRealityPointerProfile. Ce type de profil est affecté à un MixedRealityInputSystemProfile dans l’inspecteur de configuration MRTK. Le profil pointeur détermine le curseur, les types de pointeurs disponibles au moment de l’exécution et la façon dont ces pointeurs communiquent entre eux pour décider lequel est actif.

  • Étendue de pointage : définit la distance maximale pour laquelle un pointeur peut interagir avec un GameObject.

  • Masque de couche Raycast pointant : il s’agit d’un tableau hiérarchisé de LayerMasks pour déterminer avec quel GameObjects possible un pointeur donné peut interagir et l’ordre d’interaction à tenter. Cela peut être utile pour s’assurer que les pointeurs interagissent d’abord avec les éléments d’interface utilisateur avant d’autres objets de scène. Exemple de profil de pointeur

Configuration des options de pointeur

La configuration par défaut du profil de pointeur MRTK inclut les classes de pointeur suivantes et les préfabriqués associés prédéfinis. La liste des pointeurs disponibles pour le système au moment de l’exécution est définie sous Options de pointeur dans le profil pointeur. Les développeurs peuvent utiliser cette liste pour reconfigurer des pointeurs existants, ajouter de nouveaux pointeurs ou en supprimer un.

Exemple de profil Options de pointeur

Chaque entrée pointeur est définie par l’ensemble de données suivant :

  • Type de contrôleur : ensemble de contrôleurs pour lequel un pointeur est valide.

    • Par exemple, le PokePointer est responsable du « poking » des objets avec un doigt et est, par défaut, marqué comme prenant uniquement en charge le type de contrôleur de main articulé. Les pointeurs ne sont instanciés que lorsqu’un contrôleur devient disponible, et en particulier le type de contrôleur définit les contrôleurs avec 2000 contrôleurs qui peuvent être créés.
  • Handness : permet à un pointeur d’être instancié uniquement pour une main spécifique (gauche/droite)

Remarque

La définition de la propriété Handedness d’une entrée Pointeur sur None la désactive efficacement du système au lieu de supprimer ce pointeur de la liste.

  • Prefab pointeur : cette ressource de préfabriqué est instanciée lorsqu’un contrôleur correspondant au type de contrôleur spécifié et à la remise commence à être suivie.

Il est possible d’associer plusieurs pointeurs à un contrôleur. Par exemple, dans DefaultHoloLens2InputSystemProfile (Assets/MRTK/SDK/Profiles/HoloLens2/), le contrôleur de main articulé est associé à PokePointer, GrabPointer et DefaultControllerPointer (c’est-à-dire les rayons de main).

Remarque

MRTK fournit un ensemble de préfabriqués de pointeurs dans Assets/MRTK/SDK/Features/UX/Prefabs/Pointers. Un nouveau préfabriqué personnalisé peut être généré tant qu’il contient l’un des scripts de pointeur dans Assets/MRTK/SDK/Features/UX/Scripts/Pointers ou tout autre script implémentant IMixedRealityPointer.

Configuration du curseur

Le curseur du regard est directement configurable via la GazeCursorPrefab propriété sur dans l’éditeur MixedRealityInputSystemProfile . Pour configurer le curseur utilisé pour d’autres pointeurs, vous devez modifier le préfabriqué utilisé dans le CursorPrefab champ du correspondant BaseControllerPointer. Pour modifier le curseur par programme, modifiez la BaseCursor propriété sur le comportement correspondant IMixedRealityPointer .

Cursor Prefab, propriété

Consultez nos préfabriqués de curseur dans Assets/MRTK/SDK/Features/UX/Prefabs/Cursors pour obtenir des exemples d’implémentation du comportement du curseur. En particulier, DefaultGazeCursor fournit une implémentation robuste de la modification du graphique du curseur en fonction de l’état contextuel.

Classes de pointeur par défaut

Les classes suivantes sont les pointeurs MRTK prédéfinis disponibles et définis dans le profil de pointeur MRTK par défaut décrit ci-dessus. Chaque préfabriqué de pointeur fourni sous Assets/MRTK/SDK/Features/UX/Prefabs/Pointers contient l’un des composants de pointeur attachés.

Pointeurs par défaut MRTK

Pointeurs éloignés

LinePointer

LinePointer, une classe de pointeur de base, dessine une ligne à partir de la source de l’entrée (c’est-à-dire le contrôleur) dans le sens du pointeur et prend en charge un seul jet de rayons dans cette direction. En règle générale, les classes enfants telles que et ShellHandRayPointer les pointeurs de téléportation sont instanciées et utilisées (qui dessinent également des lignes pour indiquer où la téléportation se termine) à la place de cette classe qui fournit principalement des fonctionnalités courantes.

Pour les contrôleurs de mouvement comme dans Oculus, Vive et Windows Mixed Reality, la rotation correspond à la rotation du contrôleur. Pour d’autres contrôleurs comme HoloLens 2 mains articulées, la rotation correspond à la position de pointage fournie par le système de la main.

LIGNE DE POINTEUR MRTK
CurvePointer

CurvePointer étend la classe LinePointer en autorisant les casts de rayons à plusieurs étapes le long d’une courbe. Cette classe de pointeur de base est utile pour les instances courbes telles que les pointeurs de téléportation où la ligne se plie constamment en une parabole.

ShellHandRayPointer

L’implémentation de ShellHandRayPointer, qui s’étend à partir de LinePointer, est utilisée par défaut pour le profil de pointeur MRTK. Le préfabriqué DefaultControllerPointer implémente la ShellHandRayPointer classe .

GGVPointer

Également connu sous le nom de pointeur Gaze/Gesture/Voice (GGV), le GGVPointer alimente les interactions d’apparence et de tapage holoLens 1, principalement via l’interaction Regarde et Air Tap ou Regard et Sélection vocale. La position et la direction du pointeur GGV sont pilotées par la position et la rotation de la tête.

TouchPointer

Le TouchPointer est responsable de l’utilisation de l’entrée Unity Touch (c’est-à-dire de l’écran tactile). Il s’agit d’interactions lointaines, car le fait de toucher l’écran projette un rayon de la caméra vers un emplacement potentiellement éloigné de la scène.

MousePointer

Le MousePointer alimente un écran en raycast universel pour les interactions lointaines, mais pour la souris au lieu de l’interaction tactile.

Pointeur de la souris

Remarque

La prise en charge de la souris n’est pas disponible par défaut dans MRTK, mais peut être activée en ajoutant un nouveau fournisseur de données d’entrée de type MouseDeviceManager au profil d’entrée MRTK et en affectant au MixedRealityMouseInputProfile fournisseur de données.

Pointeurs proches

PokePointer

Le PokePointer est utilisé pour interagir avec des objets de jeu qui prennent en charge « l’interaction proche tactile ». qui sont des GameObjects qui ont un script attaché NearInteractionTouchable . Dans le cas d’UnityUI, ce pointeur recherche NearInteractionTouchableUnityUIs. Le PokePointer utilise un SphereCast pour déterminer l’élément tactile le plus proche et est utilisé pour alimenter des éléments tels que les boutons pressables.

Lors de la configuration du GameObject avec le NearInteractionTouchable composant, veillez à configurer le paramètre localForward pour qu’il pointe à l’avant du bouton ou d’un autre objet qui doit être rendu tactile. Assurez-vous également que les limites de l’objet tactile correspondent aux limites de l’objet tactile.

Propriétés utiles du pointeur Poke :

  • TouchableDistance : distance maximale avec laquelle une surface tactile peut être interagissante
  • Visuels : objet de jeu utilisé pour afficher le visuel de pointe du doigt (l’anneau sur le doigt, par défaut).
  • Ligne : ligne facultative pour dessiner du bout des doigts vers la surface d’entrée active.
  • Masque de couche Poke : tableau hiérarchisé de LayerMasks pour déterminer les GameObjects possibles avec lesquels le pointeur peut interagir et l’ordre d’interaction à tenter. Notez qu’un GameObject doit également avoir un NearInteractionTouchable composant pour interagir avec un pointeur poke.
Pointeur Poke
SpherePointer

SpherePointer utilise UnityEngine.Physics.OverlapSphere afin d’identifier l’objet le plus NearInteractionGrabbable proche pour l’interaction, ce qui est utile pour une entrée « saisissable » comme le ManipulationHandler. À l’instar de la PokePointer/NearInteractionTouchable paire fonctionnelle, pour pouvoir interagir avec le pointeur Sphere, l’objet de jeu doit contenir un composant qui est le NearInteractionGrabbable script.

Pointeur de récupération

Propriétés utiles du pointeur Sphere :

  • Rayon de cast de la sphère : rayon de la sphère utilisée pour interroger les objets pouvant être saisis.
  • Marge de l’objet proche : distance au-dessus du rayon de cast de sphère à interroger pour détecter si un objet se trouve près du pointeur. Total Near Object detection radius is Sphere Cast Radius + Near Object Margin
  • Angle du secteur de l’objet proche : angle autour de l’axe avant du pointeur pour l’interrogation des objets à proximité. Fait fonctionner la IsNearObject requête comme un cône. Cette valeur est définie sur 66 degrés par défaut pour correspondre au comportement d’Hololens 2

Pointeur de sphère modifié pour rechercher uniquement les objets dans la direction vers l’avant

  • Facteur de lissage de l’objet proche : facteur de lissage pour la détection d’objets proches. Si un objet est détecté dans le rayon de l’objet proche, le rayon interrogé devient rayon d’objet proche * (1 + facteur de lissage de l’objet proche) pour réduire la sensibilité et rendre plus difficile pour un objet de quitter la plage de détection.
  • Saisir des masques de couche : tableau hiérarchisé de LayerMasks pour déterminer les GameObjects possibles avec lesquels le pointeur peut interagir et l’ordre d’interaction à tenter. Notez qu’un GameObject doit également avoir un NearInteractionGrabbable pour interagir avec un SpherePointer.

    Remarque

    La couche Reconnaissance spatiale est désactivée dans le préfabriqué GrabPointer par défaut fourni par MRTK. Cela permet de réduire l’impact sur les performances de l’exécution d’une requête de chevauchement de sphères avec le maillage spatial. Vous pouvez l’activer en modifiant le préfabriqué GrabPointer.

  • Ignore Colliders Not in FOV : indique s’il faut ignorer les colliders qui peuvent être proches du pointeur, mais pas réellement dans le FOV visuel. Cela peut empêcher les saisies accidentelles, et permettra aux rayons de la main de s’allumer lorsque vous êtes peut-être près d’une capture, mais ne peut pas le voir. L’objet Visual FOV est défini via un cône au lieu du frustum classique pour des raisons de performances. Ce cône est centré et orienté de la même manière que le frustum de l’appareil photo avec un rayon égal à la demi-hauteur d’affichage (ou au FOV vertical).
Pointeur sphere

Pointeurs de téléportation

  • TeleportPointer déclenche une demande de téléportation quand une action est prise (c’est-à-dire que le bouton de téléportation est enfoncé) afin de déplacer l’utilisateur.
  • ParabolicTeleportPointer déclenche une demande de téléportation quand une action est prise (c’est-à-dire que le bouton de téléportation est enfoncé) avec un raycast de ligne parabolique afin de déplacer l’utilisateur.
Pointeur parabolique

Prise en charge des pointeurs pour les plateformes de réalité mixte

Le tableau suivant détaille les types de pointeurs généralement utilisés pour les plateformes courantes dans MRTK. REMARQUE : il est possible d’ajouter différents types de pointeurs à ces plateformes. Par exemple, vous pouvez ajouter un pointeur Poke ou Un pointeur Sphere à VR. En outre, les appareils VR dotés d’un boîtier de commande peuvent utiliser le pointeur GGV.

Pointeur OpenVR Windows Mixed Reality HoloLens 1 HoloLens 2
ShellHandRayPointer Valide Valide Valide
TeleportPointer Valide Valide
GGVPointer Valide
SpherePointer Valide
PokePointer Valide

Interactions de pointeur via le code

Interfaces d’événement de pointeur

Les monoBehaviours qui implémentent une ou plusieurs des interfaces suivantes et qui sont affectés à un GameObject avec un Collider recevront des événements d’interaction de pointeur tels que définis par l’interface associée.

Événement Description Handler
Avant le changement de focus/changement de focus Déclenché sur l’objet de jeu qui perd le focus et celui qui le gagne chaque fois qu’un pointeur change de focus. IMixedRealityFocusChangedHandler
Focus Entrée/Sortie Déclenché sur l’objet de jeu qui obtient le focus lorsque le premier pointeur y entre et sur celui qui perd le focus lorsque le dernier pointeur le quitte. IMixedRealityFocusHandler
Pointeur vers le bas / Glissé / Vers le haut / Cliqué Déclenché pour appuyer sur le pointeur de rapport, le faire glisser et le relâcher. IMixedRealityPointerHandler
Interaction tactile démarrée / mise à jour / terminée Déclenché par des pointeurs tactiles comme PokePointer pour signaler l’activité tactile. IMixedRealityTouchHandler

Remarque

IMixedRealityFocusChangedHandler et IMixedRealityFocusHandler doivent être gérés dans les objets sur lesquels ils sont déclenchés. Il est possible de recevoir des événements de focus globalement, mais, contrairement à d’autres événements d’entrée, le gestionnaire d’événements globaux ne bloque pas la réception des événements en fonction du focus (l’événement sera reçu à la fois par le gestionnaire global et un objet correspondant dans le focus).

Événements d’entrée de pointeur en action

Les événements d’entrée de pointeur sont reconnus et gérés par le système d’entrée MRTK de la même manière que les événements d’entrée standard. La différence est que les événements d’entrée de pointeur sont gérés uniquement par le GameObject dans le focus par le pointeur qui a déclenché l’événement d’entrée, ainsi que tous les gestionnaires d’entrée globaux. Les événements d’entrée réguliers sont gérés par gameObjects dans le focus pour tous les pointeurs actifs.

  1. Le système d’entrée MRTK reconnaît qu’un événement d’entrée s’est produit
  2. Le système d’entrée MRTK déclenche la fonction d’interface appropriée pour l’événement d’entrée sur tous les gestionnaires d’entrée globaux inscrits
  3. Le système d’entrée détermine quel GameObject est activé pour le pointeur qui a déclenché l’événement
    1. Le système d’entrée utilise le système d’événements d’Unity pour déclencher la fonction d’interface appropriée pour tous les composants correspondants sur le GameObject ciblé
    2. Si, à un moment donné, un événement d’entrée a été marqué comme utilisé, le processus se termine et aucun autre GameObjects ne reçoit de rappels.
      • Exemple : les composants implémentant l’interface IMixedRealityFocusHandler seront recherchés pour un GameObject qui gagne ou perd le focus
      • Remarque : Le système d’événements Unity va monter en bulles pour rechercher le GameObject parent si aucun composant correspondant à l’interface souhaitée n’est trouvé sur le GameObject actuel.
  4. Si aucun gestionnaire d’entrée global n’est inscrit et qu’aucun GameObject n’est trouvé avec un composant/interface correspondant, le système d’entrée appelle chaque gestionnaire d’entrée inscrit de secours

Exemple

Voici un exemple de script qui modifie la couleur du convertisseur attaché lorsqu’un pointeur prend ou quitte le focus ou lorsqu’un pointeur sélectionne l’objet.

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler
{
    private Color color_IdleState = Color.cyan;
    private Color color_OnHover = Color.white;
    private Color color_OnSelect = Color.blue;
    private Material material;

    private void Awake()
    {
        material = GetComponent<Renderer>().material;
    }

    void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
    {
        material.color = color_OnHover;
    }

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

    void IMixedRealityPointerHandler.OnPointerDown(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerDragged(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
    {
        material.color = color_OnSelect;
    }
}

Pointeurs de requête

Il est possible de rassembler tous les pointeurs actuellement actifs en effectuant une boucle dans les sources d’entrée disponibles (c’est-à-dire les contrôleurs et les entrées disponibles) pour découvrir les pointeurs qui y sont attachés.

var pointers = new HashSet<IMixedRealityPointer>();

// Find all valid pointers
foreach (var inputSource in CoreServices.InputSystem.DetectedInputSources)
{
    foreach (var pointer in inputSource.Pointers)
    {
        if (pointer.IsInteractionEnabled && !pointers.Contains(pointer))
        {
            pointers.Add(pointer);
        }
    }
}

Pointeur principal

Les développeurs peuvent s’abonner à l’événement FocusProviders PrimaryPointerChanged pour être avertis lorsque le pointeur principal dans le focus a changé. Cela peut être extrêmement utile pour déterminer si l’utilisateur interagit actuellement avec une scène par le biais du regard, d’un rayon de main ou d’une autre source d’entrée.

private void OnEnable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.SubscribeToPrimaryPointerChanged(OnPrimaryPointerChanged, true);
}

private void OnPrimaryPointerChanged(IMixedRealityPointer oldPointer, IMixedRealityPointer newPointer)
{
    ...
}

private void OnDisable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.UnsubscribeFromPrimaryPointerChanged(OnPrimaryPointerChanged);

    // This flushes out the current primary pointer
    OnPrimaryPointerChanged(null, null);
}

La PrimaryPointerExample scène (Assets/MRTK/Examples/Demos/Input/Scenes/PrimaryPointer) montre comment utiliser le pour que les PrimaryPointerChangedHandler événements répondent à un nouveau pointeur principal.

Exemple de pointeur principal

Résultat du pointeur

La propriété pointeur Result contient le résultat actuel de la requête de scène utilisée pour déterminer l’objet avec le focus. Pour un pointeur de raycast, comme ceux créés par défaut pour les contrôleurs de mouvement, l’entrée du regard et les rayons de la main, il contient l’emplacement et la normale de la frappe du raycast.

private void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
{
    var result = eventData.Pointer.Result;
    var spawnPosition = result.Details.Point;
    var spawnRotation = Quaternion.LookRotation(result.Details.Normal);
    Instantiate(MyPrefab, spawnPosition, spawnRotation);
}

La PointerResultExample scène (Assets/MRTK/Examples/Demos/Input/Scenes/PointerResult/PointerResultExample.unity) montre comment utiliser le pointeur Result pour générer un objet à l’emplacement d’accès.

Résultat du pointeur

Désactiver les pointeurs

Pour activer et désactiver les pointeurs (par exemple, pour désactiver le rayon de main), définissez pour PointerBehavior un type de pointeur donné via PointerUtils.

// Disable the hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

// Disable hand rays for the right hand only
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);

// Disable the gaze pointer
PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOff);

// Set the behavior to match HoloLens 1
// Note, if on HoloLens 2, you must configure your pointer profile to make the GGV pointer show up for articulated hands.
public void SetHoloLens1()
{
    PointerUtils.SetPokePointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGrabPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGGVBehavior(PointerBehavior.Default);
}

Consultez PointerUtils et TurnPointersOnOff pour plus d’exemples.

Interactions de pointeur via l’éditeur

Pour les événements de pointeur gérés par IMixedRealityPointerHandler, MRTK offre une commodité supplémentaire sous la PointerHandler forme du composant, ce qui permet de gérer directement les événements de pointeur via les événements Unity.

Gestionnaire de pointeurs

Étendue du pointeur

Les pointeurs de distance ont des paramètres qui limitent la distance à laquelle ils vont raycast et interagir avec d’autres objets de la scène. Par défaut, cette valeur est définie sur 10 mètres. Cette valeur a été choisie pour rester cohérente avec le comportement de l’interpréteur de commandes HoloLens.

Cela peut être modifié en mettant à jour les DefaultControllerPointer champs du composant du ShellHandRayPointer préfabriqué :

Étendue du pointeur : contrôle la distance maximale avec laquelle les pointeurs interagissent.

Étendue du pointeur par défaut : contrôle la longueur du rayon/de la ligne pointeur qui s’affiche lorsque le pointeur n’interagit avec rien.

Voir aussi