So I have been wracking my brain trying to figure this out. So I need to calculate how far ahead to aim for 1 spaceship to fire and hit another spaceship. I need to know this so when the player targets another ship a targeting bracket shows up where the player needs to fire at that point in time.
I know there is a code already written to do this on the wiki, however I am not understanding how it works. I am scripting in JS. Any help with this would be greatly appreciated.
Ok, i don’t see your problem… Do you want to understand how it works or how you can use it?
Just copy the code in this section:
into a new C-sharp script that is located in Standard Assets. Then you can use the function even in JS.
using UnityEngine;
using System.Collections;
public class Intercept
{
//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);
return targetPosition + t*(targetRelativeVelocity);
}
//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
}
}
In JS you can use it like this:
// I'll assume that both target and shooter are rigidbodies
var target : Transform;
var shotSpeed : float;
function Update()
{
var interceptionPoint = Intercept.FirstOrderIntercept(transform.position, rigidbody.velocity, shotSpeed, target.position, target.rigidbody.velocity);
// Do what you want
}