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
, IXRSelectInteractor
et 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.