Tengo un modelo 3D de una torreta que gira alrededor del eje Y. Esta torreta tiene un cañón que está significativamente fuera del centro del objeto. Quiero que el cañón, no la torreta, apunte a un objetivo específico. Sin embargo, solo puedo rotar la torreta y, por lo tanto, no sé qué ecuación debo aplicar para lograr por objetivo.
La siguiente imagen ilustra mi problema:
Si tengo la torreta "LookAt ()" en el objetivo, un láser que se origina en el cañón perderá por completo dicho objetivo.
Si este fuera un escenario completamente de arriba hacia abajo, y el cañón fuera exactamente paralelo a la torreta, entonces mi lógica me dice que el objetivo falso debe ubicarse en una posición que sea igual al objetivo real más un desplazamiento que sea igual al Torreta y el cañón. Sin embargo, en mi escenario real, mi cámara está en ángulo 60º, y el cañón tiene una ligera rotación.
La siguiente imagen ilustra el escenario:
No estoy seguro exactamente por qué, pero si aplico ese mismo desplazamiento, solo parece funcionar mientras apunto a ciertas distancias de la torreta.
¿Mi lógica es defectuosa? ¿Me estoy perdiendo algo fundamental aquí?
Edición final: la solución proporcionada por la última actualización de @JohnHamilton resuelve este problema con una precisión perfecta. Ahora he eliminado el código y las imágenes que utilicé para ilustrar mis implementaciones incorrectas.
fuente
Respuestas:
La respuesta es bastante fácil si haces los cálculos. Tiene una distancia fija de Y y una distancia variable de X (Ver Imagen 1). Necesitas encontrar el ángulo entre Z y X y girar tu torreta mucho más.
Paso 1: obtenga la distancia entre la línea de la torreta (V) y la línea de la pistola (W) que es Y (esto es constante pero no hace daño calcular). Obtenga la distancia de la torreta al objetivo (que es X).
Paso 2: divida Y entre X y luego obtenga el seno hiperbólico del valor
Paso 3: gire la torreta mucho más (alrededor del eje que va de arriba hacia abajo, probablemente hacia arriba pero solo usted puede conocer esa parte).
Por supuesto, en este caso, es necesario que gire en sentido antihorario, por lo que es posible que deba agregar un signo menos delante del ángulo de giro allí, como en
-turnAngle
.Editado algunas partes. Gracias a @ens por señalar la diferencia en la distancia.
El OP dijo que su arma tiene un ángulo, así que aquí vamos, imagen primero, explicación después:
Ya sabemos del cálculo anterior dónde apuntar la línea roja de acuerdo con la línea azul. Apuntando primero a la línea azul:
El único cálculo que difiere aquí es el cálculo de "X Prime" (X ') porque el ángulo entre la pistola y la torreta (ángulo "a") cambió la distancia entre las líneas.
La siguiente parte SÓLO es necesaria si está haciendo las pistolas de torreta modulares (es decir, el usuario puede cambiar las pistolas en una torreta y diferentes pistolas tienen ángulos diferentes). Si está haciendo esto en el editor, ya puede ver cuál es el ángulo de la pistola según la torreta.
Hay dos métodos para encontrar el ángulo "a", uno es el método transform.up:
La técnica anterior se calculará en 3D, por lo que si desea un resultado en 2D, debe deshacerse del eje Z (eso es lo que supongo donde está la gravedad, pero si no cambió nada, en Unity es el eje Y que está arriba o abajo, es decir, la gravedad está en el eje Y, por lo que puede que tenga que cambiar las cosas)
La segunda forma es el método de rotación (estoy pensando en 2D en este caso):
Nuevamente, todos estos códigos le darán valores que son positivos, por lo que es posible que tenga que sumar o restar la cantidad dependiendo del ángulo (también hay cálculos para eso, pero no voy a profundizar en eso). Un buen lugar para comenzar con esto sería el
Vector2.Dot
método en Unity.Bloque final de código para una explicación adicional de lo que estamos haciendo:
Si hiciste todo bien, deberías obtener una escena como esta ( enlace para el paquete de la unidad ): lo que quiero decir con valores siempre positivos:
El método Z puede dar valores negativos:
Para una escena de ejemplo, obtenga el paquete de la unidad desde este enlace .
Aquí está el código que he usado en la escena (en la torreta):
Código adaptado 3D con X y Z como plano 2D:
fuente
También podría usar un enfoque más general:
La matemática para su problema ya existe en forma de producto escalar (o producto de puntos) . Solo necesita obtener las direcciones del eje delantero de sus armas y la dirección de su arma al objetivo.
Deja que W sea el vector de avance de tu arma.
Deja que D sea la dirección de tu arma a tu objetivo. (Target.pos - Weapon.pos)
Si resuelve la fórmula del producto dot
para alfa, obtienes:
Solo tienes que convertir radianes a grados y tienes tu ángulo para rotar tu robot. (Como mencionaste, el arma está en ángulo con tu robot, por lo que debes agregar el ángulo a alfa)
fuente
Todas las respuestas publicadas hasta ahora son (más o menos) incorrectas, así que aquí hay una solución rápida y correcta:
Para apuntar el arma hacia el objetivo, gire el vector de la torreta hacia el objetivo y agregue el ángulo θ.
Entonces encontremos θ:
Cuando
δ' = 0
esto se simplifica aθ = asin(a / d)
, que coincide con la primera parte de la respuesta de John Hamilton.Editar:
He agregado un ejemplo de trabajo.
Abra en JSFiddle o use el fragmento incrustado a continuación:
fuente