Search Unity

2D projectile trajectory prediction

Discussion in '2D' started by skakac-33, Nov 30, 2013.

  1. skakac-33

    skakac-33

    Joined:
    Oct 6, 2013
    Posts:
    8
    I have problems with predicting trajectory
    I'm using:
    Code (csharp):
    1.  
    2. Vector2 startPos;
    3. float power = 10.0f;
    4. float interval = 1/30.0f;
    5. GameObject[] ind;
    6.  
    7.  
    8. void Start (){
    9.         transform.rigidbody2D.isKinematic = true;
    10.         ind = new GameObject[dots];
    11.         for(int i = 0; i<dots; i++){
    12.             GameObject dot = (GameObject)Instantiate(Dot);
    13.             dot.renderer.enabled = false;
    14.             ind[i] = dot;
    15.         }
    16.     }
    17.  
    18. void Update (){
    19.         if(shot) return;
    20.         if(Input.GetAxis("Fire1") == 1){
    21.             if(!aiming){
    22.                 aiming = true;
    23.                 startPos = Input.mousePosition;
    24.                 ShowPath();
    25.             }
    26.             else{
    27.                 CalculatePath();
    28.             }
    29.            
    30.         }
    31.         else if(aiming  !shot){
    32.             transform.rigidbody2D.isKinematic =  false;
    33.             transform.rigidbody2D.AddForce(GetForce(Input.mous  ePosition));       
    34.             shot = true;
    35.             aiming = false;
    36.             HidePath();
    37.         }
    38. }
    39.  
    40. Vector2 GetForce(Vector3 mouse){
    41.         return (new Vector2(startPos.x, startPos.y)- new Vector2(mouse.x, mouse.y))*power;
    42.        
    43. }
    44.  
    45. void CalculatePath(){
    46.         ind[0].transform.position = transform.position; //set frist dot to ball position
    47.         Vector2 vel = GetForce(Input.mousePosition); //get velocity
    48.  
    49.         for(int i = 1; i < dots; i++){         
    50.             ind[i].renderer.enabled = true; //make them visible
    51.             Vector3 point = PathPoint(transform.position, vel, i); //get position of the dot
    52.             point.z = -1.0f;
    53.             ind[i].transform.position = point;
    54.         }
    55.     }
    56.  
    57.     Vector2 PathPoint(Vector2 startP, Vector2 startVel, int n){
    58.                //Standard formula for trajectory prediction
    59.         float t = interval;
    60.         Vector2 stepVelocity = t*startVel;
    61.         Vector2 StepGravity = t*t*Physics.gravity;
    62.  
    63.         Vector2 whattoreturn = ((startP + (n * stepVelocity)+(n*n+n)*StepGravity) * 0.5f);
    64.  
    65.         return whattoreturn;
    66.     }
    67.  
    68.  
    69.  
    70.  
    Using this, I get wrong trajectory.
    1. It's like gravity doesn't drag trajectory down at all, and yes i know that gravity is weak because:
    Code (csharp):
    1.  
    2. t*t*Physics.gravity = 0.03^2 * vector2(0, -9.8) = vector2(0, -0.00882)
    3.  
    But that is the formula :S
    2. Since gravity is low, velocity is too strong.

    Here is the video:
    http://tinypic.com/player.php?v=1z50w3m&s=5



    Trajectory formula form:
    http://www.iforce2d.net/b2dtut/projected-trajectory


    What should I do?

    I found that if I set
    StepGravity to something stronger like (0, -0.1)
    and devide startVel by 8
    I get nearly right trajectory, but i don't want that, I need true trajectory path.
     
    Last edited: Nov 30, 2013
  2. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    Try:

    Code (csharp):
    1.  
    2. Vector2 PathPoint(Vector2 startP, Vector2 startVel, float t)
    3. {
    4.     return startP + startVel * t + 0.5f * Physics2D.gravity * t * t;
    5. }
    6.  
    For startVel in units per second, this tells you the position of the projectile after t seconds.

    Edit: if you want to keep using the formula you were using before, I think you multiplied too many copies of "t" into the step gravity term, but it doesn't really make sense to use that kind of formula unless you synchronise the 'interval' with the physics timestep. In practise it is simpler to use a the general continuous integration formula, and it should give results that are just as accurate in general, except in the case where gravity is extremely high.
     
    Last edited: Dec 2, 2013