realistic throwing/flying curve of an object

Hi Guys.
We are coding a 2D Sidescroller at the moment. But we have a problem with our Throw-Script. It should throw an object towards a target and that process should look nearly realistic. There should be some sort of gravitiy which slows the speed of the object towards the high point of its flying curve and then start to get faster when it hits towards the target/ground.

Could some of you gentlemen help us? :slight_smile:

thats the script so far:


using UnityEngine;
using System.Collections;

public class Throw : MonoBehaviour
{
    public Transform Target;
    public float firingAngle = 45.0f;
    public float gravity = 9.8f;

    bool direction = true;

    public Transform Projectile;

    void Start()
    {
        StartCoroutine(SimulateProjectile());
    }

    IEnumerator SimulateProjectile()
    {
        // Short delay added before Projectile is thrown
        yield return new WaitForSeconds(1.5f);

        // Move projectile to the position of throwing object + add some offset if needed.
        Projectile.position = transform.position + new Vector3(0, 0.0f, 0);

        // Calculate distance to target
        float targetDistance = Vector3.Distance(Projectile.position, Target.position);
        if (Target.position.x > Projectile.position.x) {
            direction = false;
        }
        // Calculate the velocity needed to throw the object to the target at specified angle.
        float projectile_Velocity = targetDistance / (Mathf.Sin(2 * firingAngle * Mathf.Deg2Rad) / gravity);
        //Debug.Log ("projectileVel: " + projectile_Velocity);
        // Extract the X  Y componenent of the velocity
        float Vx = Mathf.Sqrt(projectile_Velocity) * Mathf.Cos(firingAngle * Mathf.Deg2Rad);
        float Vy = Mathf.Sqrt(projectile_Velocity) * Mathf.Sin(firingAngle * Mathf.Deg2Rad);
        Debug.Log ("VX: " + Vx + "+" + "VY: " + Vy);
        // Calculate flight time.
        float flightDuration = targetDistance / Vx;

        Rotate projectile to face the target.
        Quaternion q = Quaternion.LookRotation(Target.position - Projectile.position);
        q.y = 0;
        Projectile.rotation = q;

        float elapse_time = 0;

        while (elapse_time < flightDuration*2)
        {
            if(direction)
                Projectile.Translate(-Vx * Time.deltaTime, (Vy - (gravity * elapse_time)) * Time.deltaTime, 0);
            else
                Projectile.Translate(Vx * Time.deltaTime, (Vy - (gravity * elapse_time)) * Time.deltaTime, 0);
            //Projectile.Translate(0, (Vy - (gravity * elapse_time)) * Time.deltaTime, Vx * Time.deltaTime);

            elapse_time += Time.deltaTime;

            yield return new WaitForSeconds(0.016f);
        }
    }

    public void Initialize(float speed, float size){
        //Aufruf direkt nach Instanziieren des Objektes
    }

    void Update(){
     
    }
}

I think RigidBody2D is what you want. You can simply assign it gravity, linear drag, mass etc. Once you give it an initial velocity of AddForce it should simulate everything you are trying to accomplish.

On a side note this is a peculiar use of a Coroutine. You probably want to move the code inside that while loop into your Update function.

Hi, like @aflesher suggested you need to add a rigid body to the gameobject you want to throw.

Then attach a simple script like this.

void Start () {
        rb = GetComponent<Rigidbody2D>();
      
        theta = 45f*3.14f/180f;
        forceDirn.x = Mathf.Cos(theta);
        forceDirn.y = Mathf.Sin(theta);
      
        // You can change this or set it in the editor itself
        float gravity = 9.8f;
        rb.gravityScale = gravity;
          
        thrust = 20f;
        rb.AddForce(forceDirn*thrust, ForceMode2D.Impulse);
    }

If you are interested check out the game attached in my signature. It involves a lot of projectiles thrown from various locations with various velocities.

1 Like