- Home /
How do i predict the position of my player for the turret to shoot at?
I have a turret and a player spaceship. this turret shoots at the player within a certain range but, as the player fliest around, every shot misses. can any of you possibly help me establish a mathmatical formula to calculate this?
what values do i need to put where etc. any help is greatly appriciated, i have been breaking my head over this for the last few days
This code from danikgames.com works perfectly
you can just destroy/disable the turret after some time as per your needs. you will need to adjust the turret speed and time for this. calculating distance every frame will not be good for performance
Hey, sorry, for that but i'm reaaaly new at unity, and at the coding at all!Could you give me the scripts you've used?
Regards, Nikola
Answer by peterho0218 · Nov 22, 2016 at 06:42 PM
We can simply solve this by using Sine Formula. For the method in Unity:
private Vector3 predictedPosition(Vector3 targetPosition, Vector3 shooterPosition, Vector3 targetVelocity, float projectileSpeed)
{
Vector3 displacement = targetPosition - shooterPosition;
float targetMoveAngle = Vector3.Angle(-displacement, targetVelocity) * Mathf.Deg2Rad;
//if the target is stopping or if it is impossible for the projectile to catch up with the target (Sine Formula)
if (targetVelocity.magnitude == 0 || targetVelocity.magnitude > projectileSpeed && Mathf.Sin(targetMoveAngle) / projectileSpeed > Mathf.Cos(targetMoveAngle) / targetVelocity.magnitude)
{
Debug.Log("Position prediction is not feasible.");
return targetPosition;
}
//also Sine Formula
float shootAngle = Mathf.Asin(Mathf.Sin(targetMoveAngle) * targetVelocity.magnitude / projectileSpeed);
return targetPosition + targetVelocity * displacement.magnitude / Mathf.Sin(Mathf.PI - targetMoveAngle - shootAngle) * Mathf.Sin(shootAngle) / targetVelocity.magnitude;
}
You may call it in Update() method to use it.
I haven't looked past your velocity > projectile because that line is wrong. Your target can have a larger magnitude than your projectile's and still intersect. For example, a target moving closer to the projectile's origin. The projectile can still intercept the target. You should check the dot product first.
Thank you for your re$$anonymous$$der. I have improved my code now.
Funny to see responses to this old thread. I actually got it working back when i asked this. The code looked something like this:
float targetDistance = Vector3.Distance(shotPos, targetPos);
float traveltime = targetDistance / bulletSpeed;
Vector3 predictedPos = targetPos + target$$anonymous$$ovement * traveltime;
return predictedPos;
This worked alright at the time, it wasnt perfect by any means but it made me not needing to deliberately program a margin of error for the turret.
This example you gave here seems much more reliable, thanks for this whole equation!
Answer by Wopsie · Jan 13, 2016 at 10:33 AM
i finally got it right only a little while before your comment! i ended up doing this: (i happened to know the speed of my bullet never changes)
//get player position
Vector3 playerPos = turretRange[0].transform.position;
//get bullet speed
float bulletSpeed = 600f * Time.fixedDeltaTime;
//calculate distance to player with pythagoras
float playerDistance = Vector3.Distance(transform.position, playerPos);
//calculate traveltime
travelTime = playerDistance / bulletSpeed;
predictedPosition = playerPos + playerData.movementVector * travelTime;
thanks a lot anyway!
That's not going to be quite right, because you calculate the travelTime based on the current player position. So the bullet is going to arrive at the current player position at the same time the player arrives at the predicted position.
well my playerdata.movementVector is the diffrence between where the player was before and after he changed position, i add that to the playerpos and multiply it by traveltime, it gives me the desired effect
Hi Wopsie, can you kindly tell me what is playerData.movementVector do??
predictedPosition = playerPos + playerData.movementVector * travelTime;