Míssil Guiado com Tempo Constante

9

Estou construindo um jogo com jogadores e mísseis.

Eu quero disparar um míssil de P1 para P2. O míssil deve sempre levar exatamente cinco segundos para atingir P2. O míssil também deve rastrear P2. Se P2 se afastar, o míssil deve acelerar para satisfazer a restrição de tempo. Se P2 se mover para a esquerda, o míssil deve se mover para a esquerda (e também mudar a velocidade). Se P2 se aproximar de P1, o míssil deve desacelerar.

Isso é possível? Qual é a melhor maneira de conseguir isso?

No momento, não tenho uma classe Vector2D (na verdade, não é um jogo, mas a analogia funciona bem); portanto, se possível, eu gostaria de uma solução que não exija uma.

Edit: Este não é realmente um míssil também. :)

Obrigado!

Pedro
fonte
11
(Tenho um pouco de medo de alguém perguntar sobre a orientação de mísseis qualificada por "este não é realmente um jogo", mas ...) Você tem alguma restrição no formato da trajetória do míssil? Ele sempre pode seguir uma linha reta entre sua posição atual e o jogador 2? Tem algum limite no raio de viragem ou aceleração? Precisa evitar obstáculos? Além disso, você menciona o Vector2D - é seguro assumir que você só precisa disso em 2D? Você pode fazer toda a matemática vetorial do componente, mas é desajeitado escrever em comparação com uma aula simples de matemática do vetor, então eu realmente não entendo a preferência em relação a isso.
DMGregory
Você perdeu algumas informações adicionais. Existem restrições? Os mísseis se movem ao longo de uma linha ou devemos nos preocupar com as direções e quantas dimensões eventualmente?
Liggiorgio
O caminho não deve ser restrito. As únicas regras são: A) O "míssil" deve sempre dar passos em direção ao seu alvo. B) O "míssil" deve sempre levar 5 segundos para chegar lá. Escrever uma classe Vector2D não é problema. Eu apenas não tenho uma prática (e matemática não é minha melhor matéria). Se facilitar, eu posso adicioná-lo.
Peter
A maneira mais simples de fazer isso é usar um spline de hermita e ler o valor paramétrico.
Steven Srun

Respostas:

11

A edição é tranquilizadora. :)

Ok, aqui está um loop de atualização simples ...

Assumindo que quando disparamos o míssil, inicializamos remainingFlightTime = 5fentão ...

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
fonte
11
Este método não faz o "míssil" parecer girar em torno do ponto de lançamento, no meio do vôo. +1
Jon
0

Por que não ler a posição e atualizar o destino de destino conforme ele muda?

Talvez você precise ver como o lerping funciona, mas seria algo como isto:

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);
}

Ao ler, você está basicamente alterando a posição de um objeto durante um certo período de tempo, para poder dizer que está 50% do caminho de A a B e o objeto seria colocado lá. A leitura é direta, assim você sempre se moverá em direção ao alvo (conforme desejar nos comentários).

user3797758
fonte
huh bem meu mal ... acho que é o que acontece se você tentar codificar às 3 da manhã. mudou a resposta para corrigir o erro
user3797758