ขีปนาวุธที่มีเวลาคงที่


9

ฉันกำลังสร้างเกมกับผู้เล่นและอาวุธ

ฉันต้องการยิงขีปนาวุธจาก P1 ถึง P2 ขีปนาวุธควรใช้เวลา 5 วินาทีในการเข้าถึง P2 ขีปนาวุธควรติดตาม P2 ด้วย ถ้า P2 เคลื่อนที่ไปไกลกว่านั้นขีปนาวุธจะต้องเร่งความเร็วขึ้นเพื่อสนองข้อ จำกัด ด้านเวลา หาก P2 เคลื่อนที่ไปทางซ้ายขีปนาวุธต้องเลื่อนไปทางซ้าย (และเปลี่ยนความเร็วเช่นกัน) ถ้า P2 เคลื่อนที่เข้าใกล้ P1 มากขึ้นขีปนาวุธจะต้องชะลอความเร็ว

เป็นไปได้ไหม วิธีที่ดีที่สุดในการทำสิ่งนี้ให้สำเร็จคืออะไร?

ขณะนี้ฉันไม่มีคลาส Vector2D (นี่ไม่ใช่เกมจริง แต่การเปรียบเทียบนั้นใช้งานได้ดี) ดังนั้นถ้าเป็นไปได้ฉันต้องการโซลูชันที่ไม่ต้องการ

แก้ไข:นี่ไม่ใช่ขีปนาวุธจริง ๆ เช่นกัน :)

ขอบคุณ!


1
(ฉันค่อนข้างกลัวคนที่ถามเกี่ยวกับแนวทางขีปนาวุธที่มีคุณสมบัติว่า "นี่ไม่ใช่เกมจริง" แต่ ... ) คุณมีข้อ จำกัด ใด ๆ เกี่ยวกับรูปร่างของวิถีวิถีของขีปนาวุธหรือไม่? มันสามารถตามเส้นตรงระหว่างตำแหน่งปัจจุบันกับผู้เล่น 2 ได้หรือไม่? มันมีข้อ จำกัด เกี่ยวกับรัศมีวงเลี้ยวหรืออัตราเร่งหรือไม่ มันจำเป็นต้องหลีกเลี่ยงอุปสรรคหรือไม่? นอกจากนี้คุณพูดถึง Vector2D - ปลอดภัยไหมที่จะสมมติว่าคุณต้องการเพียงแค่ 2D เท่านั้น? คุณสามารถทำส่วนประกอบคณิตศาสตร์เวกเตอร์ได้ทั้งหมด แต่มันเป็นเรื่องยากที่จะเขียนเมื่อเทียบกับคลาสคณิตศาสตร์เวกเตอร์อย่างง่ายดังนั้นฉันจึงไม่เข้าใจการตั้งค่านี้
DMGregory

คุณพลาดข้อมูลเพิ่มเติมบางส่วน มีข้อ จำกัด หรือไม่ ขีปนาวุธเคลื่อนที่ไปตามแนวเส้นหรือเราควรสนใจเกี่ยวกับทิศทางและในที่สุดจะมีมิติขนาดเท่าใด?
liggiorgio

เส้นทางไม่ควรถูก จำกัด กฎเดียวคือ: A) "ขีปนาวุธ" ควรทำตามเป้าหมายเสมอ B) "ขีปนาวุธ" ควรใช้เวลา 5 วินาทีเพื่อไปที่นั่น การเขียนคลาส Vector2D นั้นไม่มีปัญหา ฉันไม่ได้มีประโยชน์เพียงอย่างเดียว (และคณิตศาสตร์ไม่ใช่วิชาที่ดีที่สุดของฉัน) หากทำได้ง่ายขึ้นฉันสามารถเพิ่มได้
ปีเตอร์

วิธีที่ง่ายที่สุดในการทำเช่นนี้คือการใช้ hermite spline และ lerp ค่าพารามิเตอร์
Steven Srun

คำตอบ:


11

การแก้ไขคือความมั่นใจ :)

โอเคนี่คือลูปการอัปเดตที่ตรงไปตรงมา ...

สมมติว่าเมื่อเรายิงขีปนาวุธเราเริ่มต้นremainingFlightTime = 5f...

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

1
วิธีนี้ไม่ทำให้ "ขีปนาวุธ" ปรากฏขึ้นเพื่อหมุนไปรอบ ๆ มันเป็นจุดปล่อยกลางอากาศ +1
จอน

0

เหตุใดจึงไม่อ่านคำตอบตำแหน่งและอัปเดตปลายทางเป้าหมายเมื่อมีการเปลี่ยนแปลง

คุณอาจต้องดูว่า lerping ทำงานอย่างไร แต่มันจะมีลักษณะดังนี้:

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

โดย lerping คุณกำลังเปลี่ยนตำแหน่งของวัตถุในช่วงระยะเวลาหนึ่งดังนั้นคุณสามารถบอกได้ว่าคุณเป็น 50% ของทางจาก A ถึง B และวางวัตถุไว้ที่นั่น Lerping นั้นโดยตรงดังนั้นคุณจะไปยังเป้าหมายเสมอ (ตามที่คุณต้องการในความคิดเห็น)


หืมมมฉันไม่ดี ... ฉันเดาว่าจะเกิดอะไรขึ้นถ้าคุณลองโค้ดตอนตีสาม เปลี่ยนคำตอบเพื่อแก้ไขข้อผิดพลาด
3797758
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.