Hey guys, I’ve been working on a missile script to make them home in on a target by estimating the intercept position every update and pointing them towards that location. Known defects/improvements are:
Only the target’s current velocity is taken into account. There is no prediction of turns or acceleration.
I also don’t take into account the missile’s own acceleration, which is known.
My missile, with this script, will hit the ship if the ship is completely stationary. It will always arrive behind the ship if the ship is moving at all, even at a slow, constant vector. It then spins around, decelerates, accelerates back at the ship, and again arriving behind the ship. Given the way my script is written and not taking into account the missile’s acceleration, I’d expect to at least strike in front of the slowly moving ship due to assumed ETA always being faster than anticipated. So, here’s my intercept method - can anyone take a look and see where I went wrong? I took calculus ~10yrs ago, so this is some mathematical stretching for me :p.
public void intercept(GameObject target, GameObject interceptor)
{
// 1) Find time for interceptor to reach target's current position: distance/speed
float interceptTime = Vector3.Distance(target.transform.position, interceptor.transform.position)/interceptor.GetComponent<Rigidbody>().velocity.magnitude;
// 2) Loop steps 2 & 3 until oldInterceptPosition and newInterceptPosition differ by < .5m
Vector3 oldInterceptPosition = target.transform.position + (interceptor.GetComponent<Rigidbody>().velocity * interceptTime);
Vector3 newInterceptPosition;
float diff = 100;
int count = 0; //<- added tripwire so Unity didn't infi-loop in here. It never reaches diff < .5f apparently
do
{
// 2.1) Find time for interceptor to reach target's newly predicted position
interceptTime = Vector3.Distance(oldInterceptPosition, interceptor.transform.position) / interceptor.GetComponent<Rigidbody>().velocity.magnitude;
// 2.2) Find the position target will move to during time of interception.
newInterceptPosition = target.transform.position + (interceptor.GetComponent<Rigidbody>().velocity * interceptTime);
// 2.3) Check the difference in distances between old and new positions
diff = Vector3.Distance(oldInterceptPosition, newInterceptPosition);
count++;
} while (diff > .5f && count < 20);
// 3) Slerp towards the estimate of intercept position
if (newInterceptPosition - transform.position != Vector3.zero)
{
Quaternion rotation = Quaternion.LookRotation(newInterceptPosition - transform.position);
float damping = 100;
interceptor.transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
}
}
I have homing missiles that do no prediction. They hit accurately. Not sure why you are doing all that extra calculation. makes no sense. If the missile wasnt tracking (like a bullet). sure it would make sense.
If you really want to get into it, this is how the bullet projection is done.
Well, for whatever reason, just going with the “1) aim at the target 2) add thrust” loop wasn’t working. Had almost the exact same result as always ending up behind the moving target. That said, yes, I do want the missiles to be able to miss the target based on fancy flying :).
Perhaps that’s a better question for me to ask right now - why don’t my simple homing missiles hit a moving, non-accelerating, target? During Update() I was running:
I’m not able to tell you based on just the code, when I get home I’ll try this code and see if I can get it to work for you your subject got me very much intrigued to try myself haha.
using UnityEngine;
public class HomingMissile : MonoBehaviour {
public GameObject target;
public float missileSpeed = 50f;
[SerializeField]
private float _distanceFromTarget;
void Update()
{
_distanceFromTarget = Vector3.Distance(this.transform.position, target.transform.position);
float step = missileSpeed * Time.deltaTime;
if(target != null)
{
this.transform.rotation = Quaternion.LookRotation(target.transform.position - this.transform.position);
this.transform.position = Vector3.MoveTowards(this.transform.position, target.transform.position, step);
}
}
}
I had the same issue with the missile just ending up missing the target at its rear and then taking too much time to turn back around and gain enough momentum to go after the target again. It happens everytime it gets close to the target.
I’m sure real homing missiles however have a system that checks how close it is to its target and adjusts maybe its speed or trajectory to make sure it will intercept the target properly.
I did a quick search on Google and came up with a nice quote from a Wiki page:
Maybe either of the pages can help us achieve our goal? haha
You can see the projectiles in a video of inferno in my sig. Hits moving targets fine.
You can make the missile miss by having a slow turn rate. Obviously the higher the turn rate, the less chance you have of getting away. Also speed of missile comes into play there. If the missile is too fast and turns too slow, likely to miss a fast target.
Apparently dealing with force on a RB missile will ensure they always miss, due to not correcting for inertia. I didn’t think it’d cause enough discrepancy between desired and actual path, but it does. If I want to go back to a thrust-based system I’ll have to correct for my current momentum.
Yep like it says on that wiki page I linked you’ll have to calculate the proper intercept path for the missile. Trying to do it at the moment just for fun, too bad I suck at math what better than to take such a difficult thing to pain myself in the evening haha.
Heh, tha’ts relatively simple. The fun is when you want to make a bullet hit a moving target. Combination of that first link + angle of reach calculation.
Now you’re just making me jealous with your wisdom haha. Do you maybe know a link or tutorial somewhere on how to read those mathmatical formulas like on that Wiki link I gave? I’ll dive into my Math 101 book from pre-school again…