Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question intercepting objects in 3D space

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

  1. JamesEmmerson


    Jun 24, 2020
    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


    Nov 21, 2010
    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


    Oct 18, 2010
    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):
    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;
    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;
    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.
  4. Xepherys


    Sep 9, 2012