Partager via


Architecture des interacteurs — MRTK3

MRTK s’appuie sur l’ensemble des interactions offertes par le Kit de ressources d’interaction XR d’Unity. Les fonctionnalités de réalité mixte comme le suivi des mains articulées, le regard et le pincement nécessitent des interactions plus complexes que l’ensemble fourni avec XRI par défaut. MRTK définit de nouvelles interfaces d’interaction, classées généralement par la modalité d’entrée et les implémentations correspondantes.

Résumé et révision

Pour les développeurs qui débutent avec XRI, nous vous recommandons de consulter d’abord la documentation de l’architecture XRI d’Unity. Les interacteurs MRTK sont des sous-classes des interacteurs XRI existants ou des implémentations des interfaces d’interaction XRI. Consultez la documentation d’Unity sur l’architecture des interacteurs qui s’applique également à MRTK.

Bons citoyens de XRI

Les interacteurs MRTK personnalisés se comportent bien par rapport aux interfaces par défaut des interacteurs XRI ; du point de vue des systèmes XRI, ils sont indiscernables des interacteurs « vanilla ». L’inverse est également vrai; lors de la création d’interactions avancées dans MRTK, les interactions XRI par défaut fonctionnent toujours pour le pointage de base et la sélection. Il fait partie de l’effort MRTK pour être entièrement compatible avec les projets XRI existants. Si vous disposez d’une application XRI, les contrôles d’interface utilisateur et d’interaction MRTK fonctionnent avec votre configuration XRI « vanilla » existante.

Abstraction de la modalité d’entrée

L’appareil d'entrée, l'interacteur qui effectue l'interaction et les événements d'interaction qu'ils génèrent sont tous isolés sur le plan architectural dans XRI. Cette isolation est essentielle à la stratégie d’abstraction d’entrée dans MRTK3 et nous permet d’écrire des interactions inter-plateformes et inter-appareils qui fonctionnent bien dans tous les contextes.

À partir de MRTK v2, il existe un instinct commun pour coder des interactions spécifiques à un type ou un appareil d’entrée particulier. De nombreux développeurs sont habitués à écrire des interactions qui réagissent spécifiquement à une saisie proche, à un rayon lointain ou à un autre type d’entrée spécifique.

Bien que MRTK3 autorise toujours l’ambiguïté et la détection des modes d’entrée individuels, les interactions codées en dur vers des types d’entrée individuels spécifiques limitent artificiellement et réduisent la flexibilité de vos interactions. Pour plus d’informations, consultez la documentation de l’architecture interagissante, mais la clé des interactions est qu’elles n’ont généralement pas besoin de mapper en 1:1 avec les appareils d’entrée.

AttachTransform et inversion du contrôle

Une grande partie de ce que MRTK v2 faisait dans les « logiques de déplacement » dans le cadre de ObjectManipulator, Slider, etc. est maintenant la responsabilité de l’interacteur lui-même. L'interacteur contrôle maintenant son attachTransform pour définir le comportement d'un type de manipulation spécifique. Vous n’avez plus besoin d’écrire sur l’interactable une logique d’interaction complexe qui diffère selon les modalités d’entrée. À la place, votre logique de manipulation unifiée peut écouter la pose de attachTransform, quelle que soit la modalité d’entrée ou l’appareil qui le pilote.

Par exemple, un attachTransform de GrabInteractor se trouve au point de saisie sur la main/contrôleur. Un attachTransform de XRRayInteractor est situé au point d’atteinte à la fin du rayon. Le attachTransform de CanvasProxyInteractor se trouve partout où la souris a cliqué. Pour tous ces différents interacteurs, l’interactable n’a pas besoin de connaître le type d’interacteur pour répondre de manière appropriée aux manipulations.

L’interactable interroge attachTransform et peut traiter tous les attachTransform de la même manière, quel que soit le type d’interacteur.

Cette approche est essentielle pour la compatibilité avec les interacteurs XRI existants, ainsi qu’en vue de la vérification future de vos interactions pour les modalités d’entrée qui n’ont pas encore été développées. Si une nouvelle méthode d'entrée est introduite, il n'est pas nécessaire de modifier les interactifs existants si le nouvel interacteur génère un attachTransform valide et qui se comporte bien.

Ainsi, philosophiquement, c’est attachTransform la logique d’interaction. Pour toutes les interactions personnalisées, préférez toujours écrire un nouvel interacteur avec une nouvelle logique attachTransform, plutôt que de réécrire ou d’étendre des interactables et de les personnaliser pour votre nouvelle interaction. De cette façon, toutes les interactions existantes peuvent profiter des avantages de votre nouvelle interaction au lieu de celles que vous avez réécrites ou étendues.

XRControllers et liaison d’entrée

La plupart des interactions ne sont pas liées directement aux actions d’entrée. La plupart dérivent de XRBaseControllerInteractor, ce qui nécessite un XRController interagissant au-dessus de la hiérarchie. Le XRController est lié aux actions d’entrée, puis propage les actions appropriées (sélectionner, etc.) à tous les interacteurs attachés.

Néanmoins, certains interacteurs peuvent avoir besoin de liaisons d'entrée spéciales ou d'une entrée supplémentaire que le XRController ne fournit pas. Dans ces cas, les interacteurs ont la possibilité de se lier directement à leurs propres actions d'entrée uniques ou même d'utiliser des sources autres que le système d'entrée pour la logique d'interaction. Les classes de base XRI préfèrent écouter les liaisons de XRController, mais ces comportements peuvent être substitués pour utiliser des sources d’entrée externes ou alternatives.

Interfaces

XRI définit les éléments de base IXRInteractor, IXRHoverInteractor, IXRSelectInteractoret IXRActivateInteractor. MRTK définit des interfaces supplémentaires pour les interacteurs. Certaines exposent des informations supplémentaires sur les interactions propres à MRTK, et d’autres sont simplement utilisées pour la catégorisation et l’identification. Ces interfaces sont toutes situées dans le package Principal, tandis que les implémentations résident dans d’autres packages, y compris Entrée.

Important

Bien que ces interfaces soient utiles si vous devez filtrer sur un type spécifique d’interaction, nous vous recommandons de ne pas coder en dur vos interactions pour écouter ces interfaces spécifiquement. Dans toutes les situations, préférez toujours le XRI générique isSelected et isHovered, plutôt qu’une interface propre à l’interaction.

Sauf en cas d’absolue nécessité, vous ne devez pas référencer les implémentations MRTK concrètes de ces interfaces dans des interactables. Dans tous les cas, il vaut mieux référencer les interfaces. Le référencement explicite des types concrets limite vos interactions à utiliser uniquement avec les types existants actuels. En référençant uniquement les interfaces, vous garantissez la compatibilité avec les implémentations futures qui peuvent ne pas sous-classer les implémentations existantes.

IVariableSelectInteractor

Les interacteurs implémentant cette interface peuvent délivrer une sélection variable (c'est-à-dire analogique) aux interactifs. La variable « sélectionner une quantité » peut être interrogée avec la propriété SelectProgress. Les interacteurs MRTK qui implémentent cette interface incluent le MRTKRayInteractor et le GazePinchInteractor. Les interactables de base (les interactables XRI par défaut et MRTKBaseInteractable) ne sont pas affectés par la quantité de la sélection de variables. Toutefois, StatefulInteractable écoute cette valeur et calcule sa Selectedness sur la base de max() pour tous les interactables variables et non variables participants.

IGazeInteractor

Les interacteurs qui implémentent cette interface représentent le regard passif de l’utilisateur, séparés de toute manipulation ou intention. L'implémentation MRTK est FuzzyGazeInteractor, qui hérite du XRI XRRayInteractor, et ajoute une logique de cone-casting floue. XRBaseInteractable signalera IsGazeHovered lorsqu’un IGazeInteractor est en cours de pointage.

IGrabInteractor

Les interacteurs qui implémentent cette interface représentent une interaction physique de saisie de champ proche. Le attachTransform est défini comme point de saisie. L’implémentation MRTK est GrabInteractor, qui sous-classe le XRDirectInteractor de XRI.

IPokeInteractor

Les interacteurs qui implémentent cette interface représentent une interaction de pincement. Notez que cela n’implique pas nécessairement le doigt ! Des interacteurs arbitraires peuvent implémenter cette interface et offrir des interactions de pincement à partir de sources autres que les doigts. Dans l'un des rares cas où la vérification des interfaces des interacteurs est une bonne idée, les interactifs comme PressableButton écoute IPokeInteractor, spécifiquement, pour piloter la presse volumétrique. Tout interacteur qui implémente IPokeInteractor induira des pressions 3D sur les boutons.

IPokeInteractor expose la propriété PokeRadius, qui définit les caractéristiques de l’objet de pincement. Le pincement est considéré comme centré sur le attachTransform et s’étend vers l’extérieur de attachTransform par le PokeRadius. Les éléments interactifs comme PressableButton décale la distance de poussée 3D par ce rayon, qui peut être déterminé par l'épaisseur du doigt physique de l'utilisateur dans le cas de poussées basées sur le doigt.

L’implémentation MRTK de cette interface est PokeInteractor. Dans notre projet modèle, nous fournissons également un autre exemple de IPokeInteractor qui n’est pas piloté par les doigts. PenInteractor fournit des interactions de type « appui avec le doigt » ancrées sur la pointe d’un stylet 3D virtuel.

IRayInteractor

Les interacteurs qui implémentent cette interface représentent une interaction de pointage basée sur les rayons. Le attachTransform représente l’emplacement de positionnement du rayon sur la surface de l’objet ciblé pendant une sélection.

L’implémentation MRTK de cette interface est MRTKRayInteractor, héritant directement de l’interface XRI XRRayInteractor.

Remarque

L’interface XRI XRRayInteractor n’implémente pas cette interface MRTK.

ISpeechInteractor

Les interacteurs qui implémentent cette interface représentent des interactions vocales. L’implémentation MRTK est SpeechInteractor.

Le SpeechInteractor MRTK, en interne, utilise PhraseRecognitionSubsystem et s’abonne aux événements d’inscription des interactables du XRInteractionManager XRI. Toutefois, les interactables n’ont pas besoin de savoir quel est le sous-système qui effectue le traitement vocal. Les ISpeechInteractor génèrent les mêmes événements XRI (sélection, etc.) que tous les autres interacteurs.

IGazePinchInteractor

Cette interface est simplement une spécialisation de l’interface IVariableSelectInteractor. Les interacteurs qui implémentent cette interface sont, implicitement, des interacteurs de sélection de variables. Les IGazePinchInteractor représentent expressément une manipulation distante indirectement ciblée. Un interacteur distinct basé sur le regard pilote la cible de l’interaction, et la manipulation est effectuée par une main ou un contrôleur. attachTransform se comporte de la même manière que attachTransform de IRayInteractor. Il s’ancre sur point de contact de la cible quand une sélection est lancée.

Lorsque plusieurs IGazePinchInteractor participent à une seule interaction, leurs attachTransform sont décalés par leur déplacement du point médian entre tous les points de pincement participants. Ainsi, les interactions interagissantes peuvent interpréter ces attachTransform de la même manière que pour toute autre interaction impliquant plusieurs mains, comme les attachTransforms avec les interactions de saisie ou de rayons.

L’implémentation MRTK est le GazePinchInteractor.

IHandedInteractor

Certains interacteurs peuvent choisir d’implémenter l’interface IHandedInteractor pour spécifier explicitement qu’ils sont associés à une main particulière d’un utilisateur. Certains interacteurs ne sont pas associés à la remise et ne l’implémentent donc pas. Les exemples les plus évidents seraient ceux comme SpeechInteractor ou FuzzyGazeInteractor.

Les interacteurs MRTK qui implémentent cette interface sont les HandJointInteractor, un XRDirectInteractor générique, abstrait piloté par une articulation de main arbitraire, le GazePinchInteractor, et le MRTKRayInteractor.

Les interactables utilisent actuellement cette interface pour déclencher certains effets quand ils sont sélectionnés, pour lesquels il faut faire la distinction entre la main gauche et la main droite. L’exemple le plus notable est l’effet d’impulsion dans la bibliothèque de composants d’expérience utilisateur.