Arquitetura Interator — MRTK3
O MRTK baseia-se no conjunto de interatores oferecidos pelo Kit de Ferramentas de Interação XR da Unity. Recursos de realidade mista, como rastreamento articulado de mãos, olhar e beliscar, exigem interatores mais elaborados do que o conjunto fornecido com XRI por padrão. MRTK define novas interfaces interatores, categorizadas geralmente pela modalidade de entrada, e implementações correspondentes.
Resumo e revisão
Para desenvolvedores novos no XRI, recomendamos que você primeiro revise a documentação da arquitetura XRI do Unity. Os interatores MRTK são subclasses de interatores XRI existentes ou implementações das interfaces interatores XRI. Consulte a documentação do Unity sobre sua arquitetura interator, que também se aplica ao MRTK.
Bons cidadãos de XRI
Os interatores MRTK personalizados são bem comportados em relação às interfaces padrão do interator XRI; do ponto de vista dos sistemas XRI, eles são indistinguíveis dos interatores "baunilha". O inverso também é verdadeiro; ao criar interactables avançados no MRTK, os interatores XRI padrão ainda funcionarão para focalização básica e seleção. Faz parte do esforço do MRTK ser totalmente compatível com os projetos XRI existentes. Se você tiver um aplicativo XRI, os controles MRTK interactables e UI funcionarão com sua configuração XRI "baunilha" existente.
Abstração da modalidade de entrada
O dispositivo de entrada, o interator que executa a interação e os eventos de interação que eles geram são todos arquitetonicamente isolados no XRI. Esse isolamento é fundamental para a estratégia de abstração de entrada no MRTK3 e nos permite escrever interações entre plataformas e entre dispositivos que funcionam bem em todos os contextos.
A partir do MRTK v2, há um instinto comum para codificar interações específicas para um determinado tipo de entrada ou dispositivo. Muitos desenvolvedores estão acostumados a escrever interações que reagem especificamente a uma captura próxima, um raio distante ou algum outro tipo de entrada específico.
Embora o MRTK3 ainda permita a desambiguação e deteção de modos de entrada individuais, as interações de codificação rígida para tipos de entrada individuais específicos limitam artificialmente e reduzem a flexibilidade de suas interações. Mais sobre isso pode ser encontrado na documentação de arquitetura interativa, mas a chave para os interatores é que eles geralmente não precisam mapear 1:1 com dispositivos de entrada.
AttachTransform e Inversão de Controle
Muito do que MRTK v2 fez em "lógicas de movimento" como parte de ObjectManipulator
, Slider
e assim por diante, é agora responsabilidade do próprio interator. O interator agora controla seu attachTransform para definir como um tipo específico de manipulação se comporta. Não é mais necessário escrever lógica de interação complexa no interacionável que difere entre as modalidades de entrada; Em vez disso, sua lógica de manipulação unificada pode ouvir a attachTransform
pose do , independentemente da modalidade de entrada ou do dispositivo que o dirige.
Por exemplo, um GrabInteractor
's está localizado no ponto de attachTransform
agarrar na mão/controlador. Um XRRayInteractor
's está localizado no ponto de attachTransform
acerto no final do raio. O CanvasProxyInteractor
's attachTransform
está localizado onde quer que o mouse tenha clicado. Para todos esses diferentes interatores, o interacionável não precisa se preocupar com o tipo de interator para responder adequadamente às manipulações.
O interactable consulta o attachTransform
e pode tratar todos attachTransform
os iguais, independentemente do tipo de interator.
Essa abordagem é crítica para a compatibilidade com interatores XRI existentes, bem como para preparar suas interações para o futuro para modalidades de entrada que ainda não foram desenvolvidas. Se um novo método de entrada for introduzido, você não precisará alterar os interactables existentes se o novo interator gerar um válido e bem comportado attachTransform
.
Assim, filosoficamente, a attachTransform
lógica da interação . Para quaisquer interações personalizadas, dê sempre preferência a escrever um novo interator com nova attachTransform
lógica em vez de reescrever ou estender interactables para serem personalizados para sua nova interação. Desta forma, todos os interactables existentes podem desfrutar dos benefícios da sua nova interação, em vez de apenas os que você reescreveu ou ampliou.
XRControllers e vinculação de entrada
A maioria dos interatores não se liga diretamente às ações de entrada. A maioria deriva de XRBaseControllerInteractor
, o que requer um XRController
interator acima do interator na hierarquia. O XRController
liga-se a ações de entrada e, em seguida, propaga as ações relevantes (selecionar, e assim por diante) para todos os interatores anexados.
No entanto, alguns interatores podem precisar de ligações de entrada especiais ou entradas adicionais que o XRController
não fornece. Nesses casos, os interatores têm a opção de se ligar diretamente às suas próprias ações de entrada exclusivas ou até mesmo usar outras fontes que não sejam do Sistema de Entrada para lógica de interação. As classes base XRI preferem ouvir as XRController
ligações do , mas esses comportamentos podem ser substituídos para usar fontes de entrada externas ou alternativas.
Interfaces
XRI define o básico IXRInteractor
, IXRHoverInteractor
, IXRSelectInteractor
, e IXRActivateInteractor
. O MRTK define interfaces adicionais para interatores. Alguns expõem informações adicionais sobre interações específicas do MRTK, e outros são simplesmente para categorização e identificação. Essas interfaces estão todas localizadas dentro do pacote Core , enquanto as implementações residem em outros pacotes, incluindo Input.
Importante
Embora essas interfaces sejam úteis se você precisar filtrar para um tipo específico de interação, recomendamos que você não codifice suas interações para ouvir essas interfaces especificamente. Em todas as situações, dê sempre preferência ao XRI genérico isSelected e isHovered, em vez de qualquer interface específica de interação.
A menos que necessário, você não deve fazer referência às implementações MRTK concretas dessas interfaces em interactables, a menos que seja absolutamente necessário. Em todos os casos, é melhor fazer referência às interfaces. Referenciar explicitamente os tipos concretos restringirá seus interactables a trabalhar apenas com os tipos atuais e existentes. Ao fazer referência apenas às interfaces, você garante a compatibilidade com implementações futuras que podem não subclassificar as implementações existentes.
IVariableSelectInteractor
Os interatores que implementam esta interface podem emitir uma seleção variável (ou seja, analógica) para os interactables. A variável select amount pode ser consultada com a SelectProgress
propriedade. Os interatores MRTK que implementam essa interface incluem o MRTKRayInteractor
e o GazePinchInteractor
. Os interactables base (os interactables XRI padrão e MRTKBaseInteractable
) não serão afetados pela quantidade de seleção variável, StatefulInteractable
no entanto, ouve esse valor e calcula Selectedness
com max()
base no de todos os interatores variáveis e não variáveis participantes.
IGazeInteractor
Os interatores que implementam essa interface representam o olhar passivo do usuário, separado de qualquer manipulação ou intenção. A implementação MRTK é FuzzyGazeInteractor
, que herda do XRI XRRayInteractor
e adiciona lógica de cone difusa. XRBaseInteractable
IsGazeHovered
sinalizará quando um IGazeInteractor
estiver pairando.
IGrabInteractor
Os interatores que implementam essa interface representam uma interação física de captura de campo próximo. O attachTransform
é definido como o ponto de atração. A implementação MRTK é GrabInteractor
, que subclasses XRI's XRDirectInteractor
.
IPokeInteractor
Os interatores que implementam essa interface representam uma interação de cutucação. Note que isso não implica necessariamente um dedo! Interatores arbitrários podem implementar essa interface e oferecer interações cutucadas de fontes que não sejam dedos. Em um dos poucos casos em que a verificação de interfaces interatores é uma boa ideia, os interactables gostam PressableButton
de ouvir IPokeInteractor
s, especificamente, para dirigir a prensa volumétrica. Qualquer interator que implemente IPokeInteractor
induzirá pressionamentos 3D em botões.
IPokeInteractor
expõe a PokeRadius
propriedade, que define as características do objeto cutucando. O poke é considerado centrado attachTransform
no e se estende para fora do attachTransform
pelo PokeRadius
. Interactables como PressableButton
deslocar sua distância de empurrar 3D por este raio, que pode ser impulsionado pela espessura física do dedo do usuário no caso de pressões baseadas em dedos.
A implementação MRTK desta interface é PokeInteractor
. Em nosso projeto de modelo, também fornecemos outro exemplo de IPokeInteractor
que não é acionado por dedos, PenInteractor
fornece interações poke enraizadas na ponta de uma caneta 3D virtual.
IRayInteractor
Os interatores que implementam essa interface representam uma interação de apontamento baseada em raios. O attachTransform
representa o local de acerto do raio na superfície do objeto alvo durante uma seleção.
A implementação MRTK desta interface é MRTKRayInteractor
, herdando diretamente do XRI XRRayInteractor
.
Nota
O XRI XRRayInteractor
não implementa essa interface MRTK.
ISpeechInteractor
Os interatores que implementam essa interface representam interações orientadas por fala. A implementação do MRTK é SpeechInteractor
.
O MRTK SpeechInteractor
, internamente, usa PhraseRecognitionSubsystem
e assina eventos de registro interacionáveis do XRI XRInteractionManager
. No entanto, os interactables não precisam se preocupar com qual subsistema está realizando o processamento da fala; ISpeechInteractor
s geram os mesmos eventos XRI (selecionar, e assim por diante) que qualquer outro interator.
IGazePinchInteractor
Esta interface é simplesmente uma especialização da IVariableSelectInteractor
interface. Os interactores que implementam esta interface são, implicitamente, interactores de seleção variável. IGazePinchInteractor
s representam expressamente uma manipulação remota indiretamente direcionada. Um interator separado baseado no olhar conduz o alvo da interação, e a manipulação é feita por uma mão ou controlador. attachTransform
se comporta da mesma formaIRayInteractor
attachTransform
: ele se encaixa no ponto de acerto no alvo quando uma seleção é iniciada.
Quando múltiplos IGazePinchInteractor
s participam de uma única interação, seus attachTransform
s são compensados por seu deslocamento do ponto mediano entre todos os pontos de pinça participantes. Assim, os interactables podem interpretá-los attachTransform
da mesma forma que interpretariam para qualquer outra interação multi-mão, como as interações de agarrar, ou interações de raios attachTransforms
.
A implementação do MRTK é o GazePinchInteractor
.
IHandedInteractor
Alguns interatores podem optar por implementar IHandedInteractor
a interface para especificar explicitamente que estão associados a uma mão específica em um usuário. Alguns interatores não estão associados ao handedness e, portanto, não implementam isso. Os exemplos mais óbvios seriam aqueles como SpeechInteractor
ou FuzzyGazeInteractor
.
Os interatores MRTK que implementam essa interface são o , um genérico, abstrato impulsionado HandJointInteractor
por uma articulação manual arbitrária, o GazePinchInteractor
, e o MRTKRayInteractor
.XRDirectInteractor
Os interactables atualmente usam essa interface para disparar certos efeitos quando selecionados que devem desambiguar entre uma mão esquerda ou direita. O exemplo mais notável disso é o efeito de pulso na biblioteca de componentes UX.