[英]2D: Moving Turret's Projectile Intercept moving target
所以我正在制作太空游戲,宇宙飛船上有炮塔。
那些炮塔需要用恆定速度的彈丸射擊移動目標。 AkA 它需要攔截並擊中目標。
當我的船和 npc 船不在同一個方向或幾乎同一個方向移動時,它工作得很好。 當他們向同一方向移動時,炮塔會在 npc 船的稍后方發射射彈。 但是一旦我轉彎,它就會始終如一地擊中 npc 船。
另外,當我站着不動時,npc 船在我面前微微開火,但當我站着不動時,我的船一直在撞擊 npc 船。
這是我的代碼:
Vector2 toTarget = (targetShip.GlobalPosition) - GlobalPosition;
Vector2 targetVel = (targetShip.dir * targetShip.speed);
Vector2 gunVelocity = (Player.currentShip.dir * Player.currentShip.playerSpeed);
Vector2 vr = targetVel - gunVelocity;
float t = AimAhead(toTarget, vr);
if(t > 0f)
{
Vector2 aimPoint = targetShip.GlobalPosition + vr * t;
dir = aimPoint - Player.currentShip.GlobalPosition;
GlobalRotation = Mathf.LerpAngle(GlobalRotation, dir.Angle(), turnRate * delta);
}
else
{
Vector2 aimPoint = targetShip.GlobalPosition;
dir = aimPoint - Player.currentShip.GlobalPosition;
GlobalRotation = Mathf.LerpAngle(GlobalRotation, dir.Angle(), turnRate * delta);
}
前方目標 function:
float a = vr.Dot(vr) - (projectile.speed * projectile.speed );
float b = 2 * vr.Dot(toTarget);
float c = toTarget.Dot(toTarget);
float det = b * b - 4 * a * c;
if (det > 0f)
{
return 2 * c / (Mathf.Sqrt(det) - b);
}
else
{
return -1f;
}
對於簡單的線性運動,這看起來是正確的:
float a = vr.Dot(vr) - (projectile.speed * projectile.speed);
float b = 2 * vr.Dot(toTarget);
float c = toTarget.Dot(toTarget);
從那里我會這樣做:
var bb = b * b;
var a2 = 2 * a;
var ac4 = 4 * a * c;
並使用此檢查:
if (bb >= ac4 && a2 != 0.0)
顯然bb >= ac4
等同於您正在使用的支票。
那么為什么a2.= 0.0
? 好吧,如果你猜對了前三行,我想你知道我們正在使用二次方程的解。 一個二次方程有兩個解,分別是(-b + sqrt(bb - ac4))/a2
和(-b - sqrt(bb - ac4))/a2
即二次方程的±:
我不想被零除。
好的,所以我們有兩種可能的解決方案。 這就是我進行的方式:
var r = Mathf.Sqrt(bb - ac4);
var times = new float[]{(-b + r)/a2, (-b - r)/a2};
var time = float.PositiveInfinity;
foreach (var candidate_time in times)
{
if (candidate_time < 0.0)
{
continue;
}
if (candidate_time < time)
{
time = candidate_time;
}
}
if (float.IsInfinity(time))
{
return -1f;
}
return time;
這是基於擊中移動目標的實現,該目標遵循您可以在其他地方找到的線段定義的路徑。 對於這個簡單的案例,我可以做更多的事情。
啊一個有趣的錯誤...
Vector2 aimPoint = targetShip.GlobalPosition + vr * t;
應該:
Vector2 aimPoint = targetShip.GlobalPosition + targetVel * t;
現在一切正常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.