Rudal Dipandu dengan Waktu Konstan

9

Saya membangun game dengan pemain dan rudal.

Saya ingin menembakkan rudal dari P1 ke P2. Rudal harus selalu membutuhkan waktu tepat lima detik untuk mencapai P2. Rudal juga harus melacak P2. Jika P2 bergerak lebih jauh, rudal harus mempercepat untuk memenuhi batasan waktu. Jika P2 bergerak ke kiri, misil harus bergerak ke kiri (dan mengubah kecepatan juga). Jika P2 bergerak lebih dekat ke P1, misil harus melambat.

Apakah ini mungkin? Apa cara terbaik untuk mencapai ini?

Saat ini saya tidak memiliki kelas Vector2D (ini sebenarnya bukan permainan, tetapi analoginya bekerja dengan baik), jadi jika memungkinkan, saya ingin solusi yang tidak memerlukannya.

Sunting: Ini sebenarnya bukan rudal juga. :)

Terima kasih!

Peter
sumber
1
(Saya agak takut pada seseorang yang bertanya tentang panduan rudal yang memenuhi syarat oleh "ini sebenarnya bukan permainan" tapi ...) Apakah Anda memiliki kendala pada bentuk lintasan rudal? Bisakah selalu mengikuti garis lurus antara posisi saat ini dan pemain 2? Apakah ia memiliki batas radius putar atau akselerasi? Apakah perlu menghindari rintangan? Juga, Anda menyebutkan Vector2D - apakah aman untuk menganggap Anda hanya membutuhkan ini dalam 2D? Anda dapat melakukan semua matematika vektor secara komponen, tetapi sulit untuk menulis dibandingkan dengan kelas matematika vektor sederhana, jadi saya tidak benar-benar mengerti preferensi terhadap ini.
DMGregory
Anda melewatkan beberapa informasi tambahan. Apakah ada kendala? Apakah rudal bergerak sepanjang garis atau haruskah kita peduli tentang arah, dan berapa banyak dimensi pada akhirnya?
liggiorgio
Jalan seharusnya tidak dibatasi. Satu-satunya aturan adalah: A) "Rudal" harus selalu mengambil langkah menuju sasarannya. B) "Rudal" harus selalu membutuhkan waktu 5 detik untuk sampai ke sana. Menulis kelas Vector2D tidak ada masalah. Saya hanya tidak punya satu berguna (dan matematika bukan subjek terbaik saya). Jika itu membuatnya lebih mudah, saya bisa menambahkannya.
Peter
Cara paling sederhana untuk melakukan ini adalah dengan menggunakan hermite spline dan beri nilai parametrik.
Steven Srun

Jawaban:

11

Hasil edit meyakinkan. :)

Oke, inilah loop pembaruan sederhana ...

Dengan asumsi ketika kita menembakkan rudal kita menginisialisasi remainingFlightTime = 5fkemudian ...

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
sumber
1
Metode ini tidak membuat "rudal" tampak berputar di sekitar titik peluncurannya, di tengah penerbangan. +1
Jon
0

Kenapa tidak lerp posisi dan memperbarui tujuan target saat itu berubah?

Anda mungkin harus melihat cara kerja lerping tetapi akan terlihat seperti ini:

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

dengan mengarahkan Anda pada dasarnya mengubah posisi suatu objek selama jangka waktu tertentu sehingga Anda dapat mengatakan bahwa Anda 50% jalan dari A ke B dan objek tersebut akan ditempatkan di sana. Lerping bersifat langsung sehingga Anda akan selalu bergerak menuju target (seperti yang Anda inginkan di komentar).

pengguna3797758
sumber
huh yah buruk saya ... saya kira itulah yang terjadi jika Anda mencoba kode jam 3 pagi. mengubah jawaban untuk memperbaiki bug
user3797758