Dela via


Interaktionsarkitektur – MRTK3

MRTK bygger på den uppsättning interaktionsfunktioner som erbjuds av Unitys XR Interaction Toolkit. Funktioner för mixad verklighet som artikulerad handspårning, blick och nyp kräver mer avancerade interagerare än den uppsättning som tillhandahålls med XRI som standard. MRTK definierar nya interaktionsgränssnitt, kategoriserade i allmänhet efter indatamodalitet och motsvarande implementeringar.

Sammanfattning och granskning

För utvecklare som är nybörjare på XRI rekommenderar vi att du först läser dokumentationen för Unitys XRI-arkitektur. MRTK-interagerare är underklasser av befintliga XRI-interaktionsmän eller implementeringar av XRI-interaktionsgränssnitten. Se Unitys dokumentation om deras interaktionsarkitektur som även gäller för MRTK.

Goda medborgare i XRI

De anpassade MRTK-interagerarna är väluppfostrade med avseende på standardgränssnitten för XRI-interaktionsorn. ur XRI-systemens perspektiv är de oskiljbara från "vanilj"-interaktionsfaktorer. Inversen är också sann; När du skapar avancerade interaktionsbara objekt i MRTK fungerar standard-XRI-interaktionsfunktionerna fortfarande för grundläggande hovring och val. Det är en del av MRTK:s arbete med att vara helt kompatibelt med befintliga XRI-projekt. Om du har ett XRI-program fungerar MRTK-interaktions- och användargränssnittskontroller med din befintliga "vanilj" XRI-konfiguration.

Abstraktion av indatamodalitet

Indataenheten, interageraren som utför interaktionen och de interaktionshändelser som de genererar är alla arkitektoniskt isolerade i XRI. Den här isoleringen är viktig för indataabstraktionsstrategin i MRTK3 och gör att vi kan skriva plattformsoberoende och enhetsöverskridande interaktioner som fungerar bra i alla kontexter.

Från MRTK v2 finns det en vanlig instinkt att koda interaktioner som är specifika för en viss indatatyp eller enhet. Många utvecklare är vana vid att skriva interaktioner som reagerar specifikt på ett nära grepp, en lång stråle eller någon annan specifik indatatyp.

Mrtk3 möjliggör fortfarande tvetydighet och identifiering av enskilda indatalägen, men hårdkodande interaktioner med specifika enskilda indatatyper begränsar artificiellt och minskar flexibiliteten i dina interaktioner. Mer information om detta finns i dokumentationen om interaktionsbar arkitektur, men nyckeln för interaktionsfaktorer är att de i allmänhet inte behöver mappa 1:1 med indataenheter.

AttachTransform och Inversion av kontroll

Mycket av vad MRTK v2 gjorde i "flytta logik" som en del av ObjectManipulator, Slideroch så vidare, är nu själva interaktionsorns ansvar. Interageraren styr nu dess attachTransform för att definiera hur en viss typ av manipulering fungerar. Man behöver inte längre skriva komplex interaktionslogik på den interaktionsbara logik som skiljer sig mellan indatamodaliteter. I stället kan din enhetliga manipulationslogik lyssna på "s"-attityden attachTransformoavsett indatamodalitet eller enheten som kör den.

Till exempel finns ett GrabInteractor's attachTransform vid grepppunkten på handen/styrenheten. En XRRayInteractor's attachTransform ligger vid träffpunkten vid strålens slut. ' CanvasProxyInteractors attachTransform finns där musen har klickat. För alla dessa olika interaktionsfaktorer behöver den interagerande inte bry sig om typen av interagerare för att kunna svara korrekt på manipulationer.

De interagerande frågorna attachTransform och kan behandla var attachTransform och en av dem oavsett interaktionstyp.

Den här metoden är viktig för kompatibilitet med befintliga XRI-interaktionsfaktorer och för att kunna framtidssäkra dina interaktioner för indatamodaliteter som ännu inte har utvecklats. Om en ny indatametod introduceras behöver du inte ändra befintliga interaktionsbara objekt om den nya interaktionsorn genererar en giltig och väluppfostrad attachTransform.

Det är alltså, filosofiskt, attachTransform interaktionslogik. För alla anpassade interaktioner bör du alltid prioritera att skriva en ny interaktion med ny attachTransform logik i stället för att skriva om eller utöka interaktionsbara objekt som ska anpassas för din nya interaktion. På så sätt kan alla befintliga interaktionsbara objekt dra nytta av fördelarna med din nya interaktion i stället för endast de som du har skrivit om eller utökat.

XRControllers och indatabindning

De flesta interagerare binder inte direkt till indataåtgärder. De flesta härleds från XRBaseControllerInteractor, som kräver en XRController över interageraren i hierarkin. Bindningarna XRController till indataåtgärderna och sprider sedan relevanta åtgärder (välj och så vidare) ned till alla anslutna interagerare.

Vissa interaktionsfaktorer kan dock behöva särskilda indatabindningar eller ytterligare indata som XRController inte tillhandahålls. I dessa fall har interagerare möjlighet att binda direkt till sina egna unika indataåtgärder eller till och med använda andra icke-indatasystemkällor för interaktionslogik. XRI-basklasserna föredrar att lyssna på XRController's bindningar, men dessa beteenden kan åsidosättas för att använda externa eller alternativa indatakällor.

Gränssnitt

XRI definierar grundläggande IXRInteractor, IXRHoverInteractor, IXRSelectInteractoroch IXRActivateInteractor. MRTK definierar ytterligare gränssnitt för interagerare. Vissa exponerar ytterligare information om MRTK-specifika interaktioner, och andra är helt enkelt för kategorisering och identifiering. Dessa gränssnitt finns alla i Core-paketet , medan implementeringarna finns i andra paket, inklusive Indata.

Viktigt!

Även om dessa gränssnitt är användbara om du behöver filtrera efter en viss typ av interaktion rekommenderar vi att du inte hårdkodar dina interaktioner för att lyssna efter dessa gränssnitt specifikt. I varje situation ska du alltid prioritera den generiska XRI isSelected och isHovered, snarare än något interaktionsspecifikt gränssnitt.

Om det inte behövs bör du inte referera till de konkreta MRTK-implementeringarna av dessa gränssnitt i interaktionsbara objekt om det inte är absolut nödvändigt. I samtliga fall är det bättre att referera till gränssnitten. Om du uttryckligen refererar till de konkreta typerna begränsas dina interaktionsbara objekt till att endast fungera med de aktuella, befintliga typerna. Genom att bara referera till gränssnitten säkerställer du kompatibilitet med framtida implementeringar som kanske inte underklassar befintliga implementeringar.

IVariableSelectInteractor

Interagerare som implementerar det här gränssnittet kan utfärda variabel (dvs. analog) urval till interaktionsbara objekt. Variabeln välj belopp kan frågas med egenskapen SelectProgress . MRTK-interagerare som implementerar det här gränssnittet innehåller MRTKRayInteractor och GazePinchInteractor. Bas-interaktionsbara objekt (standard-XRI-interaktionsbara objekt och MRTKBaseInteractable) påverkas inte av variabelns urvalsmängd. StatefulInteractableLyssnar dock på det här värdet och beräknar dess Selectedness baserat på max() alla deltagande variabel- och icke-variabla interaktionsfaktorer.

IGazeInteractor

Interagerare som implementerar det här gränssnittet representerar användarens passiva blick, separat från alla manipulationer eller avsikter. MRTK-implementeringen är FuzzyGazeInteractor, som ärver från XRI XRRayInteractoroch lägger till fuzzy cone-casting-logik. XRBaseInteractable flaggar IsGazeHovered när en IGazeInteractor hovrar.

IGrabInteractor

Interagerare som implementerar det här gränssnittet representerar en fysisk interaktion nära fältet. attachTransform Definieras som grepppunkten. MRTK-implementeringen är GrabInteractor, som underklassar XRI:s XRDirectInteractor.

IPokeInteractor

Interagerare som implementerar det här gränssnittet representerar en petande interaktion. Observera att detta inte nödvändigtvis innebär ett finger! Godtyckliga interaktionsfaktorer kan implementera det här gränssnittet och erbjuda petande interaktioner från icke-fingerkällor. I en av de få instanser där kontroll av interaktionsgränssnitt är en bra idé är interaktionsbara objekt som PressableButton att lyssna efter s, specifikt, för IPokeInteractoratt driva volympress. Alla interagerare som implementerar IPokeInteractor kommer att inducera 3D-tryck på knappar.

IPokeInteractor exponerar PokeRadius egenskapen, som definierar egenskaperna för poking-objektet. Poke anses vara centrerad på attachTransform och sträcker sig utåt från attachTransform av PokeRadius. Interaktionsbara objekt som PressableButton förskjuter sitt 3D-push-avstånd med den här radien, som kan drivas av användarens fysiska fingertjocklek när det gäller fingerbaserade tryckningar.

MRTK-implementeringen av det här gränssnittet är PokeInteractor. I vårt mallprojekt ger vi också ett annat exempel på IPokeInteractor som inte är fingerdrivet. PenInteractor Det ger poke-interaktioner som är rotade på spetsen på en virtuell 3D-penna.

IRayInteractor

Interagerare som implementerar det här gränssnittet representerar en ray-baserad pekinteraktion. attachTransform Representerar strålens träffplats på målobjektets yta under en markering.

MRTK-implementeringen av det här gränssnittet är MRTKRayInteractor, ärver direkt från XRI XRRayInteractor.

Kommentar

XRI XRRayInteractor implementerar inte det här MRTK-gränssnittet.

ISpeechInteractor

Interagerare som implementerar det här gränssnittet representerar taldrivna interaktioner. MRTK-implementeringen är SpeechInteractor.

MRTK SpeechInteractoranvänder PhraseRecognitionSubsystem och prenumererar internt på interaktionsbara registreringshändelser från XRI XRInteractionManager. Interaktionsbara objekt behöver dock inte bry sig om vilket undersystem som utför talbearbetning. ISpeechInteractors genererar samma XRI-händelser (välj och så vidare) som andra interagerare gör.

IGazePinchInteractor

Det här gränssnittet är helt enkelt en specialisering av IVariableSelectInteractor gränssnittet. Interagerare som implementerar det här gränssnittet är implicit interagerare med variabelval. IGazePinchInteractors uttryckligen representerar en indirekt riktad fjärrmanipulering. En separat blickbaserad interagerare styr interaktionens mål, och manipuleringen sker av en hand eller kontrollant. attachTransform beter sig på samma sätt som IRayInteractor's attachTransform gör; den fäster mot träffpunkten på målet när ett val initieras.

När flera IGazePinchInteractordeltar i en enda interaktion förskjuts deras attachTransforms av deras förskjutning från medianpunkten mellan alla deltagande nyppunkter. Därför kan interaktionsbara objekt tolka dessa attachTransformpå samma sätt som de skulle göra för andra interaktioner med flera händer, till exempel attachTransforms interaktioner från grab eller ray-interaktioner.

MRTK-implementeringen är GazePinchInteractor.

IHandedInteractor

Vissa interagerare kan välja att implementera IHandedInteractor gränssnitt för att uttryckligen ange att de är associerade med en viss hand på en användare. Vissa interagerare är inte associerade med handlighet och implementerar därför inte detta. De mest uppenbara exemplen skulle vara sådana som SpeechInteractor eller FuzzyGazeInteractor.

MRTK-interagerarna som implementerar det här gränssnittet är HandJointInteractor, en generisk, abstrakt XRDirectInteractor som drivs av en godtycklig handfog, GazePinchInteractor, och MRTKRayInteractor.

Interaktionsbara objekt använder för närvarande det här gränssnittet för att utlösa vissa effekter när de väljs som måste skiljas mellan en vänster eller höger hand. Det mest anmärkningsvärda exemplet på detta är pulseffekten i biblioteket för UX-komponenter.