0

So I have created spaceship shooter game where ships have turrets on them . Now I want those turrets to shoot a moving target meaning I want the projectile to intercept and hit the target that is headed in some direction. Every projectile has its own speed which is constant. Also the ship which has the turret is also moving at a constant speed.

So far I have made this:

Vector2 toTarget = targetShip.GlobalPosition - Player.currentShip.GlobalPosition;
Vector2 targetVel = (targetShip.dir.Normalized() * targetShip.speed * delta) - (Player.currentShip.dir.Normalized() * Player.currentShip.speed * delta);
float distance = toTarget.Length();

float a = targetVel.Dot(targetVel) - (projectile.speed * projectile.speed); float b = 2 * targetVel.Dot(toTarget); float c = -distance * distance; //toTarget.Dot(toTarget);

float p = -b / (2 * a); float q = Mathf.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q; float t2 = p + q;

if (t1 < 0 && t2 < 0) { return; }

float timeToInterception = 1; if (t1 > 0 && t2 > 0) timeToInterception = Mathf.Min(t1, t2); //else //timeToInterception = Mathf.Max(t1, t2);

Vector2 aimSpot = targetShip.GlobalPosition + targetVel * timeToInterception; dir = aimSpot - GlobalPosition; GlobalRotation = Mathf.LerpAngle(GlobalRotation, dir.Angle(), turnRate * delta);

The Global Rotation is where the turret will look at and it shoots from its barrel. The method kinda works and sometimes does not work(the projectiles shoot behind the moving target). Vector2 targetVel = ( targetShip.dir.Normalized() * targetShip.speed * delta) - (Player.currentShip.dir.Normalized() * Player.currentShip.speed * delta); that part is me calculating velocities I am not sure if its correct...

I commented out the else part because the turrets just disappear from my ship if I let that be there and I am also uneducated why.

I've read THIS answer from this forum but I don't understand it especially his edit part. In his edit part I don't understand where to plug that projectile velocity. Also why is my turret disappearing when I uncomment else in my code?

If someone can give me some explanation I would be very thankful!

Almo
  • 6,678
  • 6
  • 36
  • 65
GoldSpark
  • 11
  • 5
  • Can you clarify what it is about the linked answer you don't understand? It seems to just be describing a standard relative velocity calculation (subtract the velocity of the frame of reference from the velocity of each entity to get their velocities relative to that frame of reference). Where do you run into trouble applying that, or other past Q&A about calculating intercept velocities/target leading? – DMGregory Nov 27 '22 at 23:51
  • Hey yea just did it in an edit. – GoldSpark Nov 27 '22 at 23:53
  • The answer does not talk about that. It's just talking about how to take the "moving shooter" out of the equation, so you can use existing answers about aiming at a moving target from a stationary shooting point. You can consult past Q&A like 1, 2, 3, 4, and more (those were just the first few results I found searching for "target leading" and "intercept moving"). – DMGregory Nov 28 '22 at 00:09
  • Thank you I will look into it. – GoldSpark Nov 28 '22 at 00:11
  • @DMGregory I am wondering am I getting velocity vector calculation right? – GoldSpark Nov 28 '22 at 13:56
  • Is the solution you posted working for you? If not, how does its behaviour differ from what you want? – DMGregory Nov 28 '22 at 14:04
  • It is working somewhat because some times the bullets are shooting behind the ship I don't know if that is normal . – GoldSpark Nov 28 '22 at 14:23
  • Never mind I had wrong direction vector in the code that is not relevant to the solution I've posted here. Its working good now. – GoldSpark Nov 28 '22 at 14:30
  • 1
    Seems duplicate of https://stackoverflow.com/questions/2248876/2d-game-fire-at-a-moving-target-by-predicting-intersection-of-projectile-and-u?noredirect=1&lq=1 which has many good answers – halt9k Feb 08 '23 at 18:06

2 Answers2

0

Leading a Target from Howling Moon Software

This tutorial helped me and it works great now! Thanks @DMGregory for the link!

This is how my code looks now:

Vector2 toTarget = (targetShip.GlobalPosition) - GlobalPosition;
Vector2 targetVel = (targetShip.dir.Normalized() * targetShip.speed);
Vector2 gunVelocity = (ownerShip.dir.Normalized() * ownerShip.speed);
Vector2 vr = targetVel - gunVelocity;

float t = AimAhead(toTarget, vr);

if (t > 0f) { Vector2 aimPoint = targetShip.GlobalPosition + targetVel * t; dir = aimPoint - GlobalPosition; GlobalRotation = Mathf.LerpAngle(GlobalRotation, dir.Angle(), turnRate * delta); }

The function AimAhead is the one that calculates everything:

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

Theraot
  • 26,532
  • 4
  • 50
  • 78
GoldSpark
  • 11
  • 5
0

You need to add

Vector3 projectileDirection = aimPoint - (ownerShip.GlobalPosition + gunVelocity * t);

to account for the ship's own speed and direction, so we subtract that speed from the final projectile direction to actually hit the target correctly.

ElectRocnic
  • 105
  • 3