Misil Guiado con Tiempo Constante

9

Estoy construyendo un juego con jugadores y misiles.

Quiero disparar un misil de P1 a P2. El misil siempre debe tomar exactamente cinco segundos para llegar a P2. El misil también debe seguir a P2. Si P2 se mueve más lejos, el misil debe acelerar para satisfacer la restricción de tiempo. Si P2 se mueve hacia la izquierda, el misil debe moverse hacia la izquierda (y también cambiar la velocidad). Si P2 se acerca a P1, el misil debe reducir la velocidad.

es posible? ¿Cuál es la mejor manera de lograr esto?

Actualmente no tengo una clase Vector2D (esto no es realmente un juego, pero la analogía funciona bien), así que si es posible, me gustaría una solución que no requiera una.

Editar: Esto tampoco es en realidad un misil. :)

¡Gracias!

Peter
fuente
1
(Tengo algo de miedo de que alguien pregunte acerca de la orientación de misiles calificada por "esto no es realmente un juego" pero ...) ¿Tiene alguna restricción en la forma de la trayectoria del misil? ¿Puede seguir siempre una línea recta entre su posición actual y el jugador 2? ¿Tiene algún límite en su radio de giro o aceleración? ¿Necesita evitar obstáculos? Además, mencionas Vector2D: ¿es seguro asumir que solo necesitas esto en 2D? Puede hacer todos los componentes matemáticos vectoriales por componentes, pero es complicado escribir en comparación con una simple clase matemática vectorial, por lo que realmente no entiendo la preferencia en contra de esto.
DMGregory
Te perdiste alguna información adicional. ¿Hay restricciones? ¿Los misiles se mueven a lo largo de una línea o deberíamos preocuparnos por las direcciones y cuántas dimensiones finalmente?
liggiorgio
El camino no debe estar limitado. Las únicas reglas son: A) El "misil" siempre debe dar pasos hacia su objetivo. B) El "misil" siempre debe tomar 5 segundos para llegar allí. Escribir una clase Vector2D no es problema. Simplemente no tengo uno a mano (y las matemáticas no son mi mejor materia). Si lo hace más fácil, puedo agregarlo.
Peter
La forma más sencilla de hacer esto es usar una spline hermita y extraer el valor paramétrico.
Steven Srun

Respuestas:

11

La edición es tranquilizadora. :)

Bien, aquí hay un ciclo de actualización sencillo ...

Suponiendo que cuando disparamos el misil, inicializamos remainingFlightTime = 5fentonces ...

void UpdateMissile(float deltaTime)
{
   remainingFlightTime -= deltaTime;

   // At the end of the trajectory, snap to target & explode.
   // The math will put us there anyway, but this saves
   // on fancy logic related to overshooting. ;)
   if(remainingFlightTime <= 0f)
   {
      myX = targetX;
      myY = targetY;
      MissileImpact();
      return;
   }

   // Compute straight-line velocity that will take us
   // to the target in exactly the time remaining.
   velocityX = (targetX - myX)/remainingFlightTime;
   velocityY = (targetY - myY)/remainingFlightTime;

   // Integrate the velocity into the position.
   myX += velocityX * deltaTime;
   myY += velocityY * deltaTime;
}
DMGregory
fuente
1
Este método no hace que el "misil" parezca girar alrededor de su punto de lanzamiento, en pleno vuelo. +1
Jon
0

¿Por qué no elevar la posición y actualizar el destino objetivo a medida que cambia?

Puede que tenga que ver cómo funciona el lerping, pero se vería así:

public position startMarker;
public float duration = 5.0f;
private float startTime;
void Launch() {
    startTime = Time.time;
}
void Update() {
    float distCovered = (Time.time - startTime) / duration;
    missile.position = Vector3.Lerp(startMarker.position, target.position, distCovered);
}

al saltar, básicamente está cambiando la posición de un objeto durante un cierto período de tiempo, por lo que podría decir que está al 50% del camino de A a B y que el objeto se colocaría allí. Lerping es directo, por lo que siempre se moverá hacia el objetivo (como lo desee en los comentarios).

usuario3797758
fuente
eh bueno mi mal ... supongo que eso es lo que pasa si intentas codificar a las 3am. cambió la respuesta para corregir el error
user3797758