Search Unity

Simple projectile motion with wind

Discussion in 'Physics' started by byerdelen, Jun 4, 2015.

  1. byerdelen

    byerdelen

    Joined:
    Mar 27, 2010
    Posts:
    68
    Hi, it is not about Unity engine physics but still it is physics

    Hi, I am a programmer myself but trigonometry is not my favourite area if things get complicated. I made a prototype that calculates the launch degrees of a thrown ball with a changing speed that is affected by changing wind(horizontal) and changing gravity(vertical), that the ball going from specific destination (character position)A to (target position)B. Then throws a projectile starting from the same angle of the character and affected by the same speed, wind, gravity. So when the player turns to the first calculated position, the projectile reaches the destination B.

    Here is the code for the prototype:

    Calculation.cs :

    Code (CSharp):
    1.  public class Calculation : MonoBehaviour
    2. {
    3. public float speed;
    4.      public float verticleangle;
    5.      public float horizontalangle;
    6.      public float windangle;
    7.      public float gravity;
    8.      public float wind;
    9.      public Transform target;
    10. public GameObject arrow;
    11. void Update ()
    12.      {
    13.    // Calculate distance to target
    14.          float target_Distance = Vector3.Distance(transform.position, target.position);
    15.          // Calculate the verticle angle needed
    16.          verticleangle = Mathf.Asin(target_Distance * gravity / speed) / 2 * Mathf.Rad2Deg;
    17.          // Calculate the horizontal angle needed
    18.          windangle = Mathf.Asin(target_Distance * wind / speed) / 2 * Mathf.Rad2Deg;
    19.          if (float.IsNaN(verticleangle))
    20.              print("outofrange");
    21.   if (Input.GetKeyDown(KeyCode.Space))
    22.              fire();
    23. }
    24.    void fire()
    25.      {
    26.          Quaternion rotation = Quaternion.LookRotation(target.position - transform.position);
    27.          GameObject temparrow = Instantiate(arrow, transform.position, transform.rotation) as GameObject;
    28.          StartCoroutine(temparrow.GetComponent<Throw>().throwaction(speed, verticleangle, windangle, gravity, wind, rotation ));
    29.      }
    30. }

    Throw.cs

    Code (CSharp):
    1. public class Throw : MonoBehaviour
    2. {
    3. public  IEnumerator throwaction(float speed, float verticleangle, float windangle, float gravity, float wind, Quaternion orgrot)
    4.      {
    5.          //Extract the X  Y componenent of the velocity
    6.          float Vx = Mathf.Sqrt(speed) * Mathf.Cos(verticleangle * Mathf.Deg2Rad);
    7.          float Vy = Mathf.Sqrt(speed) * Mathf.Sin(verticleangle * Mathf.Deg2Rad);
    8.          float Vz = Mathf.Sqrt(speed) * Mathf.Sin(windangle * Mathf.Deg2Rad);
    9.          Quaternion newrot = transform.rotation;
    10.          float elapse_time = 0;
    11.          Vector3 oldpos;
    12.          while (true)
    13.          {
    14.              elapse_time += Time.deltaTime;
    15.              transform.rotation = newrot;
    16.              oldpos = transform.position;
    17.              //Move the projectile
    18.              transform.position += Vx * Time.deltaTime * ( transform.forward);
    19.              transform.position += (  - (gravity * elapse_time)) * Time.deltaTime * (transform.up);
    20.              transform.position += ( - (wind * elapse_time)) * Time.deltaTime * (-transform.right);
    21.              //Rotate the player
    22.              transform.rotation = Quaternion.LookRotation(transform.position - oldpos);
    23.              if (elapse_time > 8)
    24.              {
    25.                  Destroy(gameObject);
    26.                  yield break;
    27.              }
    28.              yield return null;
    29.          }
    30.      }
    31. }
    Can someone tell me what is going wrong in this code?

    Here is the working prototype as web build to try out:

    Web build

    Here is my prototype that I am using:

    Prototype

    Thanks
     
  2. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Well for 1, at
    Code (CSharp):
    1.   transform.position += (  - (gravity * elapse_time)) * Time.deltaTime * (transform.up);
    2.   transform.position += ( - (wind * elapse_time)) * Time.deltaTime * (-transform.right);
    you forgot to insert Vy and Vz before the -
    This brings you relatively close.

    I am not good at math ;)
    Maybe your math is correct, but floating point error is making it a bit off.
     
  3. byerdelen

    byerdelen

    Joined:
    Mar 27, 2010
    Posts:
    68
    I did not put Vy and Vz by purpose so the arrow would go straight when I throw from the start point. But It changed all the calculations and it is not working well anymore.
    Also floating point wouldn't make much difference. I believe it is about combining wind and gravity together should have another type of calculation, they can not be calculated differently