Eu tenho um modelo 3D de uma torre que gira em torno do eixo Y. Esta torre possui um canhão que fica significativamente fora do centro do objeto. Quero que o canhão, não a torre, mire em um alvo especificado. Porém, só posso girar a torre e, portanto, não sei que equação preciso aplicar para realizar por objetivo.
A imagem a seguir ilustra meu problema:
Se eu tiver a torre "LookAt ()" no alvo, um laser originário do canhão errará completamente o alvo.
Se esse era um cenário completamente descendente e o canhão estivesse exatamente paralelo à torre, minha lógica me diz que o alvo falso deve estar localizado em uma posição igual ao alvo real mais um deslocamento igual ao entre o torre e canhão. No entanto, no meu cenário atual, minha câmera está angulada a 60º e o canhão tem uma leve rotação.
A imagem a seguir ilustra o cenário:
Não sei exatamente por que, mas se eu aplicar esse mesmo deslocamento, ele apenas funcionará enquanto visar certas distâncias da torre.
Minha lógica é falha? Estou perdendo algo fundamental aqui?
Edição final: a solução fornecida pela atualização mais recente do @JohnHamilton resolve esse problema com precisão perfeita. Agora removi o código e as imagens que usei para ilustrar minhas implementações incorretas.
fonte
Respostas:
A resposta é realmente muito fácil se você fizer as contas. Você tem uma distância fixa de Y e uma distância variável de X (veja a figura 1). Você precisa descobrir o ângulo entre Z e X e transformar sua torre muito mais.
Etapa 1 - Obtenha a distância entre a linha da torre (V) e a linha da arma (W), que é Y (isso é constante, mas não custa calcular). Distância da torre ao alvo (que é X).
Etapa 2 - Divida Y por X e obtenha o Seno Hiperbólico do valor
Etapa 3 - Gire a torre muito mais (em torno do eixo que vai de cima para baixo, provavelmente acima do eixo, mas somente você pode conhecer essa parte).
É claro que, nesse caso, você precisa girar no sentido anti-horário para adicionar um sinal de menos na frente do turnAngle, como em
-turnAngle
.Editou algumas partes. Agradecemos a @ens por apontar a diferença de distância.
O OP disse que sua arma tinha um ângulo, então aqui vamos nós, primeiro a imagem, a explicação depois:
Já sabemos no cálculo anterior onde apontar a linha vermelha de acordo com a linha azul. Então, visando a linha azul primeiro:
O único cálculo que difere aqui é o cálculo de "X Prime" (X ') porque o ângulo entre a pistola e a torre (ângulo "a") alterou a distância entre as linhas.
Esta próxima parte é SOMENTE necessária se você estiver usando as armas de torre modulares (ou seja, o usuário pode mudar as armas em uma torre e armas diferentes têm ângulos diferentes). Se você estiver fazendo isso no editor, já poderá ver qual é o ângulo da pistola de acordo com a torre.
Existem dois métodos para encontrar o ângulo "a", um é o método transform.up:
A técnica acima será calculada em 3D. Portanto, se você deseja um resultado 2D, precisa se livrar do eixo Z (é isso que eu suponho onde está a gravidade, mas se você não mudou nada, no Unity é o eixo Y que está para cima ou para baixo, ou seja, a gravidade está no eixo Y, então você pode precisar mudar as coisas):
A segunda maneira é o método de rotação (estou pensando em 2D neste caso):
Novamente, todos esses códigos fornecerão valores positivos, portanto, você pode adicionar ou subtrair a quantidade dependendo do ângulo (também existem cálculos para isso, mas não vou detalhar isso). Um bom lugar para começar com isso seria o
Vector2.Dot
método no Unity.Bloco final de código para explicação adicional do que estamos fazendo:
Se você fez tudo certo, deve ter uma cena como esta ( link para o unitypackage ): O que quero dizer com valores sempre positivos:
O método Z pode dar valores negativos:
Para uma cena de exemplo, obtenha o unitypackage neste link .
Aqui está o código que usei na cena (na torre):
Código 3D adaptado com X e Z como plano 2D:
fonte
Você também pode usar uma abordagem mais geral:
A matemática do seu problema já existe na forma do produto escalar (ou produto escalar) . Você só precisa obter as direções do seu eixo dianteiro e a direção da sua arma para o alvo.
Seja W o vetor avançado da sua arma.
Seja D a direção da sua arma para o seu alvo. (Target.pos - Arma.pos)
Se você resolver a fórmula do produto escalar
para alfa, você obtém:
Você só precisa converter radianos em graus e tem seu ângulo para girar seu robô. (Como você mencionou, a arma está em ângulo com o seu robô, então você precisa adicionar o ângulo em alfa)
fonte
Todas as respostas postadas até agora estão (mais ou menos) erradas, então aqui está uma solução rápida e correta:
Para apontar a arma na direção do alvo, gire o vetor da torre para frente e adicione o ângulo θ.
Então, vamos encontrar θ:
Quando
δ' = 0
isso simplifica paraθ = asin(a / d)
, o que corresponde à primeira parte da resposta de John Hamilton.Editar:
Eu adicionei um exemplo de trabalho.
Abra no JSFiddle ou use o snippet incorporado abaixo:
fonte