# Question intercepting objects in 3D space

Discussion in 'Scripting' started by JamesEmmerson, Sep 4, 2020.

1. ### JamesEmmerson

Joined:
Jun 24, 2020
Posts:
2
I am fully aware that this is quite a common question. I have a player space ship and I want to calculate a position so that an enemy ship can shoot at me when I am moving and have a marker on the screen to help the player shoot at the enemy when it is moving.
I have found lots of threads asking this question all with very different answers and maths, some of these seem to be badly explained and/or wrong. Could someone show me the maths to do this or a link to a thread with an answer that you know is correct. Any help will be much appreciated.

2. ### exiguous

Joined:
Nov 21, 2010
Posts:
1,749
You take the speed of your projectile, calculate how long it will travel to the target (distance), then you calculate the position the target will have in that time. This is the point you want to shoot at. Usually this is done iterative until the positions don't differ much between 2 iterations. Note that any change of speed and/or rotation of the target will make your calculated point less optimal. But I have not seen a solution which also incoporates that. And there should be a "chance" to miss for the player anyway. I would be more interested to know why with all those fancy future tech weapons have still to be aimed manually .

3. ### Bunny83

Joined:
Oct 18, 2010
Posts:
4,190
While this does work, it's not a great approach. Depending on the speed ratio between the projectile and the target it can get really off. It also highly depends on the angle.

A long time ago I made a WebPlayer example for this answer over here. I just created a WebGL build and updated my answer.

I'll copy my method over here, just in case the links don't work in the future:

Code (CSharp):
1.
2. public static Vector3 CalculateInterceptCourse(Vector3 aTargetPos, Vector3 aTargetSpeed, Vector3 aInterceptorPos, float aInterceptorSpeed)
3. {
4.      Vector3 targetDir = aTargetPos - aInterceptorPos;
5.      float iSpeed2 = aInterceptorSpeed * aInterceptorSpeed;
6.      float tSpeed2 = aTargetSpeed.sqrMagnitude;
7.      float fDot1 = Vector3.Dot(targetDir, aTargetSpeed);
8.      float targetDist2 = targetDir.sqrMagnitude;
9.      float d = (fDot1 * fDot1) - targetDist2 * (tSpeed2 - iSpeed2);
10.      if (d < 0.1f)  // negative == no possible course because the interceptor isn't fast enough
11.          return Vector3.zero;
12.      float sqrt = Mathf.Sqrt(d);
13.      float S1 = (-fDot1 - sqrt) / targetDist2;
14.      float S2 = (-fDot1 + sqrt) / targetDist2;
15.      if (S1 < 0.0001f)
16.      {
17.          if (S2 < 0.0001f)
18.              return Vector3.zero;
19.          else
20.              return (S2) * targetDir + aTargetSpeed;
21.      }
22.      else if (S2 < 0.0001f)
23.          return (S1) * targetDir + aTargetSpeed;
24.      else if (S1 < S2)
25.          return (S2) * targetDir + aTargetSpeed;
26.      else
27.          return (S1) * targetDir + aTargetSpeed;
28. }
This does even work when the projectile is slower than the enemy, given there's enough room / time. Of course it's still just a prediction based on the current velocity. So any future direction or velocity changes of course can not be considered.

Xepherys likes this.

Joined:
Sep 9, 2012
Posts:
204