I have been trying to use the following script I found to calculate lead/interception points:
using UnityEngine;
public static class InterceptPointCalculator
{
//first-order intercept using absolute target position
public static Vector3 FirstOrderIntercept(Vector3 shooterPosition,
Vector3 shooterVelocity,
float shotSpeed,
Vector3 targetPosition,
Vector3 targetVelocity)
{
Vector3 targetRelativeVelocity = targetVelocity - shooterVelocity;
float t = FirstOrderInterceptTime(shotSpeed,
targetPosition - shooterPosition,
targetRelativeVelocity);
Vector3 interceptPoint = targetPosition + t * (targetRelativeVelocity);
return interceptPoint;
}
//first-order intercept using relative target position
public static float FirstOrderInterceptTime(float shotSpeed,
Vector3 targetRelativePosition,
Vector3 targetRelativeVelocity)
{
float velocitySquared = targetRelativeVelocity.sqrMagnitude;
if (velocitySquared < 0.001f)
{
return 0f;
}
float a = velocitySquared - shotSpeed * shotSpeed;
//handle similar velocities
if (Mathf.Abs(a) < 0.001f)
{
float t = -targetRelativePosition.sqrMagnitude
/ (2f * Vector3.Dot(targetRelativeVelocity,
targetRelativePosition));
return Mathf.Max(t, 0f); //don't shoot back in time
}
float b = 2f * Vector3.Dot(targetRelativeVelocity, targetRelativePosition),
c = targetRelativePosition.sqrMagnitude,
determinant = b * b - 4f * a * c;
if (determinant > 0f)
{ //determinant > 0; two intercept paths (most common)
float t1 = (-b + Mathf.Sqrt(determinant)) / (2f * a),
t2 = (-b - Mathf.Sqrt(determinant)) / (2f * a);
if (t1 > 0f)
{
if (t2 > 0f)
{
return Mathf.Min(t1, t2); //both are positive
}
else
{
return t1; //only t1 is positive
}
}
else
{
return Mathf.Max(t2, 0f); //don't shoot back in time
}
}
else if (determinant < 0f) //determinant < 0; no intercept path
{
return 0f;
}
else //determinant = 0; one intercept path, pretty much never happens
{
return Mathf.Max(-b / (2f * a), 0f); //don't shoot back in time
}
}
}
I have two main questions:
-
I believe the script returns zero FirstOrderInterceptTime (resulting in the target’s position) if there is no possible intercept point. That is, if the shooter/shot is too slow to ever reach the target on its current path at its current speed. But is there a way to find the closest possible point to the target that the shooter could get along its path (assuming the target is flying relatively toward the shooter)?
-
I can’t seem to find much use for the shooter’s velocity in the above code. When the shooter’s velocity is zero, the shot is always accurate. But when the shooter’s velocity is not zero, the shots miss. If the shooter goes relatively toward the target, the shots fall short. The only way I could get the shots to always be accurate is to just input Vector3.zero as the shooter’s velocity. What is the purpose of the shooter’s velocity?
Thank you! ![]()