Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Target movement prediction for projectile

Discussion in 'Scripting' started by Qriva, Sep 13, 2023.

  1. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,108
    I want to fire a projectile towards moving target, and to do so I need to find position to aim for.
    upload_2023-9-13_3-59-44.png
    Target position and velocity is known, as well as gun position and projectile speed (assume constant speed).
    What is the best (performence) method to do this task?


    I tried to search some resources, and there is a lot of dead links. I found two working methods, but I am unable to understand how they work. The first one look like this:
    Code (CSharp):
    1. private Vector3 predictedPosition(Vector3 targetPosition, Vector3 shooterPosition, Vector3 targetVelocity, float projectileSpeed)
    2.     {
    3.         Vector3 displacement = targetPosition - shooterPosition;
    4.         float targetMoveAngle = Vector3.Angle(-displacement, targetVelocity) * Mathf.Deg2Rad;
    5.         //if the target is stopping or if it is impossible for the projectile to catch up with the target (Sine Formula)
    6.         if (targetVelocity.magnitude == 0 || targetVelocity.magnitude > projectileSpeed && Mathf.Sin(targetMoveAngle) / projectileSpeed > Mathf.Cos(targetMoveAngle) / targetVelocity.magnitude)
    7.         {
    8.             Debug.Log("Position prediction is not feasible.");
    9.             return targetPosition;
    10.         }
    11.         //also Sine Formula
    12.         float shootAngle = Mathf.Asin(Mathf.Sin(targetMoveAngle) * targetVelocity.magnitude / projectileSpeed);
    13.         return targetPosition + targetVelocity * displacement.magnitude / Mathf.Sin(Mathf.PI - targetMoveAngle - shootAngle) * Mathf.Sin(shootAngle) / targetVelocity.magnitude;
    14.     }
    I understand velocity and projectile speed check, but for example I don't get the part with sine/cosine. Anyway the thing is it looks quite expansive even when optimized, so I wanted to do better and I think there is faster method in this article, but my little brain don't understand the equation, or rather from where it comes exactly, why those factors are used as a,b,c, plus I am curious if there is even better method than this.
    Code (CSharp):
    1. protected float AimAhead(Vector3 delta, Vector3 vr, float muzzleV)
    2.         {
    3.             // Quadratic equation coefficients a*t^2 + b*t + c = 0
    4.             float a = Vector3.Dot(vr, vr) - muzzleV * muzzleV;
    5.             float b = 2f * Vector3.Dot(vr, delta);
    6.             float c = Vector3.Dot(delta, delta);
    7.  
    8.             float det = b * b - 4f * a * c;
    9.  
    10.             // If the determinant is negative, then there is no solution
    11.             if (det > 0f)
    12.             {
    13.                 return 2f * c / (Mathf.Sqrt(det) - b);
    14.             }
    15.             else
    16.             {
    17.                 return -1f;
    18.             }
    19.         }
     
  2. ijmmai

    ijmmai

    Joined:
    Jun 9, 2023
    Posts:
    188
    ChatGTP describes it this way. May not fit your scenario completely, but maybe it will put you on the right track.



    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class CollisionPrediction : MonoBehaviour
    4. {
    5.     public Vector3 P1; // Initial position of object 1
    6.     public Vector3 V1; // Velocity of object 1
    7.     public Vector3 P2; // Initial position of object 2
    8.     public Vector3 V2; // Velocity of object 2
    9.  
    10.     public Vector3 CollisionPoint; // Point of collision
    11.     public float TimeToCollision; // Time at which collision occurs
    12.  
    13.     void Start()
    14.     {
    15.         // Calculate relative velocity and displacement
    16.         Vector3 relativeVelocity = V2 - V1;
    17.         Vector3 relativeDisplacement = P2 - P1;
    18.  
    19.         // Calculate time to collision
    20.         TimeToCollision = Vector3.Dot(relativeDisplacement, relativeVelocity) / relativeVelocity.sqrMagnitude;
    21.  
    22.         // Calculate collision point
    23.         CollisionPoint = P1 + V1 * TimeToCollision;
    24.  
    25.         // Display the results
    26.         Debug.Log("Collision Point: " + CollisionPoint);
    27.         Debug.Log("Time to Collision: " + TimeToCollision);
    28.     }
    29. }
    30.  
     
  3. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,108
    Well, I wanted real human to help me, this is why I created thread here.
    ChatGPT lies, and will probably give me suboptimal or wrong solution, actually I think the code you posted is wrong (but I did not test it), and does not even solve my question as I don't know projectile velocity as vector, I know projectile speed.
     
  4. ijmmai

    ijmmai

    Joined:
    Jun 9, 2023
    Posts:
    188
    Oh boy, that allergic huh?

    I am not using chatGTP for my own coding, but since I am not that familiar with all the possibilities of Unity, from time to time it helps to get a grasp of what the work flow could be. For correct code to fit somone's own scenario you still need to be able to have some coding skills. Sorry it doesn't work for you.
     
  5. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,108
    ChatGPT is great tool in general, but it's not reliable, so I don't like it so much, because I simply can't trust what it says. In any case I don't want to discuss about gpt capabilities here :D, and thanks for trying to help me.
     
    ijmmai likes this.