- Home /
Calculating 3D Physics Prediction of Shot Direction with Moving target and moving gun (inertia)
Hi. I need to predict the target position of a moving object in a 3d world for a gun to fire from a distance and hit the moving object.
So far it works perfect when the player is not moving. However when the player starts moving things become tricky. The bullets speed is not constant. It depends on the player's vector3 in comparison to the bullets trajectory. For instance shooting straight forward adds the player's speed to the bulletspeed and vice versa.
My calculation is currently dependent on a constant bullet-speed, which is problematic since the player's ship affects the bullets speed. If anyone has any tips I would be very happy! (google has helped me so far, but with the "inertia" problem (shipspeed+= bulletspeed), I'm lost).
This is my code so far:
private Vector3 GetDirectionToShoot(Vector3 targetPos, Vector3 targetVelocity)
{
Vector3 totarget = targetPos - Ship.Position;
targetVelocity -= Ship.LinearVelocity;
float bulletSpeed = Ship.GunInfo.ProjectileSpeed;
//bulletSpeed -= Vector3.Distance(Ship.LinearVelocity, targetVelocity);
float a = Vector3.Dot(targetVelocity, targetVelocity) - (bulletSpeed * bulletSpeed);
float b = 2 * Vector3.Dot(targetVelocity, totarget);
float c = Vector3.Dot(totarget, totarget);
float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);
float t1 = p - q;
float t2 = p + q;
float t;
if (t1 > t2 && t2 > 0)
{
t = t2;
}
else
{
t = t1;
}
Vector3 aimSpot = targetPos + targetVelocity * t;
Vector3 bulletPath = aimSpot - Ship.Position;
float timeToImpact = bulletPath.Length() / bulletSpeed;//speed must be in units per second
return aimSpot;
}
EDIT Made a new easier formula, that should work mathematically with my limited knowledge. But seems to be malfunctioning as well. The new method was like this:
private Vector3 GetDirectionToShoot(WorldObject target)
{
Vector3 aimSpot = (target.Position - Ship.Position) * Ship.GunInfo.ProjectileSpeed +
target.LinearVelocity - Ship.LinearVelocity;
return aimSpot;
}
i'm likely mis-understanding, but it sounds like you have some code which calculates the bullet trajectory for a moving target if the player is standing still, and need to modify it to account for the player moving ? if that's the case i think you would just subtract the player velocity from the target velocity before doing your calculation.
Na that wont work since the bullets velocity also get changed by the players velocity. it would work if the bullet velocity was always the same.
well right.
assu$$anonymous$$g you have something like
vec3 calcBulletInitialVelocityForStationaryPlayer(vec3 playerPos, vec3 targetPos, vec3 targetVel) {...}
then you could write
vec3 calcBulletInitialVelocityFor$$anonymous$$ovingPlayer(vec3 playerPos, vec3 playerVel, vec3 targetPos, vec3 targetVel) {
return calcBulletInitialVelocityForStationaryPlayer(playerPos, targetPos, targetVel - playerVel) + playerVel;
}
Answer by Simpowitch · Sep 20, 2019 at 11:54 PM
http://answers.unity.com/comments/1666745/view.html
However the code on the wiki is actually tested and works properly: http://wiki.unity3d.com/index.php/Calculating_Lead_For_Projectiles?_ga=2.83628886.131956639.1568980243-1605833034.1542013817#Calculating_the_intercept_point
From Bunny83.
Note. For me to make this work I had to subtract the currentPosition of the ship/player from the recived Vector3 from the method on this website. To further improve my targeting I searched for targets more towards the front of the ship/player, since shooting backwards is dependent on your bullet speed vs. player speed, which in my case often resulted in a miss since my ship speed was close to the same as the bullet speed.