Visão geral do Solver

Solucionador Principal

Solucionadores são componentes que facilitam os meios de calcular a orientação de posição de um objeto & de acordo com um algoritmo predefinido. Um exemplo pode estar a colocar um objeto na superfície que o raio de observação do utilizador atinge atualmente.

Além disso, o sistema Solver define deterministicamente uma ordem de operações para estes cálculos de transformação, uma vez que não existe uma forma fiável de especificar para a Unidade a ordem de atualização dos componentes.

Os Solucionadores oferecem uma gama de comportamentos para anexar objetos a outros objetos ou sistemas. Um outro exemplo seria um objeto de tag-along que paira na frente do utilizador (com base na câmara). Um solucionador também pode ser ligado a um controlador e um objeto para fazer o objeto tag-along ao longo do controlador. Todos os solucionadores podem ser empilhados com segurança, por exemplo, um comportamento de tag-along + magnetismo superficial + impulso.

Como usar um solucionador

O sistema Solver é composto por três categorias de scripts:

  • Solver: A classe abstrata base de que todos os solucionadores derivam. Fornece rastreio estatal, parâmetros de suavização e implementação, integração automática do sistema de solucionamento e ordem de atualização.
  • SolverHandler: Define o objeto de referência para rastrear (ex: a chave de transformação, raio manual, etc.), pega na recolha de componentes solucionadores e executa-os na ordem adequada.

A terceira categoria é o solucionador em si. Os seguintes solucionadores fornecem os blocos de construção para o comportamento básico:

  • Orbital: Bloqueios a uma posição especificada e compensados a partir do objeto referenciado.
  • ConstantViewSize: Escamas para manter um tamanho constante em relação à vista do objeto referenciado.
  • RadialView: Mantém o objeto dentro de um cone de vista lançado pelo objeto referenciado.
  • Follow: Mantém o objeto dentro de um conjunto de limites definidos pelo utilizador do objeto referenciado.
  • InBetween: Mantém um objeto entre dois objetos rastreados.
  • SurfaceMagnetism: lança raios para superfícies do mundo, e alinha o objeto a essa superfície.
  • DirectionalIndicator: Determina a posição e orientação de um objeto como indicador direcional. A partir do ponto de referência do SolverHandler Tracked Target, este indicador orientará-se para o DirectionalTarget fornecido.
  • Momentum: Aplica aceleração/velocidade/atrito para simular impulso e mola para um objeto movido por outros solucionadores/componentes.
  • HandConstraint: Os constrangimentos opõem-se a seguir as mãos numa região que não intersecta o GameObject com as mãos. Útil para conteúdo interativo limitado à mão, como menus, etc. Este solucionador destina-se a trabalhar com o IMixedRealityHand, mas também funciona com o IMixedRealityController.
  • HandConstraintPalmUp: Deriva do HandConstraint mas inclui lógica para testar se a palma está virada para o utilizador antes da ativação. Este solucionador funciona apenas com controladores IMixedRealityHand, com outros tipos de controlador este solucionador irá comportar-se tal como a sua classe base.

Para utilizar o sistema Solver, basta adicionar um dos componentes listados acima a um GameObject. Uma vez que todos os Solvers requerem um SolverHandler , um será criado automaticamente pela Unidade.

Nota

Exemplos de como utilizar o sistema Solvers podem ser encontrados no ficheiro SolverExamples.scene.

Como alterar a referência de rastreio

A propriedade tracked Target Type do componente define o ponto de referência que todos os solucionadores usarão para calcular os seus algoritmos. Por exemplo, um tipo de valor Head com um simples componente SurfaceMagnetism resultará num raycast da cabeça e na direção do olhar do utilizador para resolver a superfície atingida. Os valores potenciais para a TrackedTargetType propriedade são:

  • Cabeça : Ponto de referência é a transformação da câmara principal
  • ControladorRa:Ponto de referência é a transformação num controlador (ou seja, a origem do ponteiro num controlador de movimento ou controlador de mão) que aponta na direção do raio de linha
    • Utilize a TrackedHandedness propriedade para selecionar a preferência de mão (i.e Esquerda, Direita, Ambos)
  • HandJoint: Ponto de referência é a transformação de uma articulação específica da mão
    • Utilize a TrackedHandedness propriedade para selecionar a preferência de mão (i.e Esquerda, Direita, Ambos)
    • Use a TrackedHandJoint propriedade para determinar a transformação da articulação para utilizar
  • CustomOverride: Ponto de referência dos atribuídos

Nota

Tanto para os tipos ControllerRay como HandJoint, o manipulador de solucionador tentará fornecer primeiro o controlador/mão esquerdo e, em seguida, o direito se o primeiro não estiver disponível ou a menos que a propriedade especifique o contrário.

Solver Tracked ObjectExemplo de várias propriedades associadas a cada TrackedTargetType

Importante

A maioria dos solucionadores usam o vetor dianteiro do alvo de transformação rastreado fornecido pelo SolverHandler . Ao utilizar um tipo de alvo rastreado da articulação da mão, o vetor dianteiro da articulação da palma pode apontar através dos dedos e não através da palma da mão. Isto depende da plataforma que fornece os dados da articulação da mão. Para simulação de entrada e Windows Mixed Reality, é o vetor para cima que aponta através da palma (ou seja, o vetor verde está para cima, o vetor azul está para a frente).

Vetor para a frente

Para superar isto, atualize a propriedade Rotação Adicional no 90,0, 0 >. Isto garantirá que o vetor dianteiro fornecido aos solucionadores está apontando através da palma e para fora da mão.

Rotação Adicional

Em alternativa, utilize o tipo de alvo rastreado pelo Controlador Ray para obter um comportamento semelhante para apontar com as mãos.

Como acorrentar solucionadores

É possível adicionar múltiplos Solver componentes ao mesmo GameObject, acorrem assim os seus algoritmos. Os SolverHandler componentes manuseiam a atualização de todos os solucionadores no mesmo GameObject. Por defeito, as SolverHandler chamadas no Start que GetComponents<Solver>() devolverão os Solucionadores na ordem que aparecem no inspetor.

Além disso, a definição da propriedade atualizada do Linked Transform para a verdade instruirá que para guardar a sua posição calculada, orientação, & escala para uma variável intermediária acessível por todos os Solvers (i.e). GoalPosition Quando for falso, o Solver irá atualizar a transformação do GameObject diretamente. Ao guardar as propriedades de transformação para um local intermediário, outros Solvers são capazes de realizar os seus cálculos a partir da variável intermediária. Isto porque a Unidade não permite atualizações para o gameObject.transform para empilhar dentro do mesmo quadro.

Nota

Os desenvolvedores podem modificar a ordem de execução dos Solvers definindo a SolverHandler.Solvers propriedade diretamente.

Como criar um novo solucionador

Todos os solucionadores devem herdar da classe base abstrata, Solver . Os requisitos primários de uma extensão solver envolvem a sobredição do SolverUpdate método. Neste método, os desenvolvedores devem atualizar os herdados GoalPosition , e propriedades para os GoalRotationGoalScale valores desejados. Além disso, é geralmente valioso alavancar SolverHandler.TransformTarget como quadro de referência desejado pelo consumidor.

O código abaixo fornecido dá um exemplo de um novo componente Solver chamado InFront que coloca o objeto anexado 2m na frente do SolverHandler.TransformTarget . Se o SolverHandler.TrackedTargetType consumidor for definido como , Head então a câmara será a SolverHandler.TransformTarget transformação da câmara e, assim, este Solver colocará o GameObject 2m em anexo à frente do olhar dos utilizadores em cada frame.

/// <summary>
/// InFront solver positions an object 2m in front of the tracked transform target
/// </summary>
public class InFront : Solver
{
    ...

    public override void SolverUpdate()
    {
        if (SolverHandler != null && SolverHandler.TransformTarget != null)
        {
            var target = SolverHandler.TransformTarget;
            GoalPosition = target.position + target.forward * 2.0f;
        }
    }
}

Guias de implementação de solver

Propriedades de solucionadores comuns

Cada componente solver tem um conjunto de propriedades idênticas que controlam o comportamento do Solver central.

Se o SeuVm estiver ativado, o Solver atualizará gradualmente a transformação do GameObject ao longo do tempo para os valores calculados. A velocidade desta mudança é determinada pela propriedade LerpTime de cada componente de transformação. Por exemplo, um valor movelerptime mais elevado resultará em incrementos mais lentos no movimento entre quadros.

Se o KeepScale estiver ativado, o Solver utilizará a escala local padrão do GameObject.

Propriedades de solver de núcleo
Propriedades comuns herdadas por todos os componentes solver

Orbital

A Orbital classe é um componente de tag-along que se comporta como planetas num sistema solar. Este Solver garantirá que o GameObject em anexo orbita em torno da transformação rastreada. Assim, se o Tipo de Alvo Rastreado do tipo de destino estiver definido para , Head então o GameObject orbitará em torno da cabeça do utilizador com uma compensação fixa aplicada.

Os desenvolvedores podem modificar esta compensação fixa para manter os menus ou outros componentes de cena ao nível dos olhos ou ao nível da cintura, etc. em torno de um utilizador. Isto é feito modificando as propriedades Local Offset e World Offset. A propriedade Do Tipo de Orientação determina a rotação aplicada ao objeto se mantiver a sua rotação original ou se estiver sempre virada para a câmara ou face qualquer transformação que esteja a conduzir a sua posição, etc.

Exemplo orbital
Exemplo orbital

RadialView

O RadialView é outro componente de tag-along que mantém uma parte particular de um GameObject dentro do frustum da visão do utilizador.

As propriedades min Max View Degrees determinam o tamanho de uma parte do GameObject sempre à vista.

As propriedades Min Max Distance determinam a distância que o GameObject deve ser mantido do utilizador. Por exemplo, caminhar em direção ao GameObject com uma Distância Min de 1m irá empurrar o GameObject para longe para garantir que nunca está mais perto do que 1 m para o utilizador.

Geralmente, o RadialView é utilizado em conjunto com o tipo de alvo RadialView definido para que o componente siga o olhar Head do utilizador. No entanto, este componente pode funcionar a manter-se à "vista" de qualquer tipo de alvo rastreado.

Exemplo RadialView
Exemplo RadialView

Seguir

A Follow classe posiciona um elemento na frente do alvo rastreado em relação ao seu eixo avançado local. O elemento pode ser vagamente limitado (também conhecido como tag-along) de modo a não seguir até que o alvo rastreado se mova para além dos limites definidos pelo utilizador.

Funciona da mesma forma que o solver RadialView, com controlos adicionais para gerir os Graus de Visualização Vertical Horizontal Max,e mecanismos para alterar a Orientação do objeto.

Siga propriedades
Siga propriedades

Siga a cena do exemplo
Siga a cena do exemplo (Ativos/MRTK/Exemplos/Demos/Solvers/Scenes/FollowSolverExample.unitity)

InBetween

A InBetween classe manterá o GameObject ligado entre duas transformações. Estes dois pontos finais de transformação são definidos pelo próprio Tipo de Alvo Rastreado do GameObject SolverHandlerSolverHandler e pela propriedade InBetween Second InBetween do componente. Geralmente, ambos os tipos serão CustomOverride definidos e os SolverHandler.TransformOverrideInBetween.SecondTransformOverride valores resultantes e os valores definidos para os dois pontos finais rastreados.

No tempo de execução, o InBetween componente criará outro SolverHandler componente baseado nas propriedades second InBetween e Second Transform SolverHandler

Os PartwayOffset defines onde ao longo da linha entre duas transformações o objeto deve ser colocado com 0,5 como meio caminho, 1.0 na primeira transformação, e 0.0 na segunda transformação.

InBetween Exemplo
Exemplo de usar o solver InBetween para manter o objeto entre duas transformações

SurfaceMagnetismo

O SurfaceMagnetism funciona através da realização de um raycast contra um conjunto de LayerMask de superfícies e colocando o GameObject nesse ponto de contacto.

O Surface Normal Offset colocará o GameObject a uma distância definida a metros da superfície na direção do normal no ponto de impacto na superfície.

Inversamente, o Surface Ray Offset colocará o GameObject a uma distância definida a metros da superfície, mas na direção oposta do raycast realizado. Assim, se o raycast for o olhar do utilizador, então o GameObject aproximar-se-á ao longo da linha desde o ponto de ataque na superfície até à câmara.

O Modo de Orientação determina o tipo de rotação a aplicar em relação ao normal na superfície.

  • Nenhuma - Nenhuma rotação aplicada
  • TrackedTarget - Objeto vai enfrentar a transformação rastreada conduzindo o raycast
  • SurfaceNormal - O objeto irá alinhar-se com base no normal no ponto de impacto na superfície
  • Misturado - O objeto alinhar-se-á com base no normal no ponto de impacto na superfície e com base na transformação rastreada.

Para forçar o GameObject associado a manter-se vertical em qualquer modo que não nenhum, ative a Orientação Vertical.

Nota

Utilize a propriedade Orientação Blend para controlar o equilíbrio entre os fatores de rotação quando o modo de orientação está definido para Misturado. Um valor de 0.0 terá uma orientação inteiramente orientada pelo modo TrackedTarget e um valor de 1.0 terá orientação inteiramente impulsionada pelo SurfaceNormal.

Exemplo doMagnetismo de Superfície

Determinar que superfícies podem ser atingidas

Ao adicionar um SurfaceMagnetism componente a um GameObject, é importante considerar a camada do GameObject e das suas crianças, se houver colisões. O componente funciona executando vários tipos de raycasts para determinar qual a superfície a "íman" contra si mesmo. Se o solucionador GameObject tiver um colisor numa das camadas listadas na MagneticSurfaces propriedade de SurfaceMagnetism , então o raycast provavelmente atingirá a si mesmo, resultando no GameObject anexando-se ao seu próprio ponto de colisão. Este comportamento estranho pode ser evitado definindo o GameObject principal e todas as crianças para a camada de Ignore Raycast ou modificando a matriz LayerMask adequadamente.

Inversamente, um SurfaceMagnetism GameObject não colidirá com superfícies numa camada não listada na MagneticSurfaces propriedade. É geralmente recomendado colocar todas as superfícies desejadas sobre uma camada dedicada (i.e Superfícies)e definir a propriedade apenas para esta camada. A utilização de predefinições ou tudo pode resultar em componentes de UI ou cursores que contribuam para o solucionador.

Finalmente, as superfícies mais distantes do que a MaxRaycastDistance configuração da propriedade serão ignoradas pelos SurfaceMagnetism raios.

Indiciador direcional

A DirectionalIndicator classe é um componente de tag-along que se orienta para a direção de um ponto desejado no espaço.

Mais utilizado quando o tipo de alvo rastreado do tipo está definido para Head . Desta forma, um componente UX com o DirectionalIndicator solucionador irá direcionar um utilizador a olhar para o ponto desejado no espaço.

O ponto desejado no espaço é determinado através da propriedade Directional Target.

Se o alvo direcional for visualizado pelo utilizador, ou qualquer que seja o quadro de referência definido no SolverHandler , então este solucionador irá desativar todos os Renderer componentes por baixo do mesmo. Se não for visível, tudo estará ativado no indicador.

O tamanho do indicador diminuirá quanto mais perto o utilizador estiver de capturar o Alvo Direcional no seu FOV.

  • Escala indicadora de min - A escala mínima para o objeto indicador

  • Escala indicadora máxima - A escala máxima para o objeto indicador

  • Fator de escala de visibilidade - Multiplicador para aumentar ou diminuir o FOV que determina se o ponto alvo direcional é visível ou não

  • Ver Offset - Do ponto de vista do quadro de referência (ou seja, a câmara possivelmente), esta propriedade define a distância na direção indicadora deve ser do centro do viewport.

Propriedades do Indicador Direcional
Propriedades do Indicador Direcional

Cena de exemplo de indicador direcional
Cena do exemplo do indicador direcional (Ativos/MRTK/Exemplos/Demos/Solvers/Cenas/DireccionalIndicatorSolverExample.unidade)

Menu de mãos com HandConstraint e HandConstraintPalmUp

Exemplo UX do menu de mão

O HandConstraint comportamento fornece um solucionador que limita o objeto rastreado a uma região segura para conteúdo limitado à mão (como uI de mão, menus, etc). Cofre regiões são consideradas áreas que não se cruzam com a mão. Uma classe derivada de HandConstraint chamada também está incluída para demonstrar um comportamento comum de HandConstraintPalmUp ativação do objeto localizado solucionado quando a palma está virada para o utilizador.

Consulte a página do Menu Manual para ver os exemplos de utilização do solucionador de restrição de mão para criar menus de mãos.

Ver também