best method of achieving parabola-like movement of an object?

Hi. truth here :slight_smile:

// I am happy to say that i have moved a little bit from the start, and will soon be celebrating a whole month learning unity on daily basis!

So i have a problem. I am making a tower defence game, and i want to add a cannon ball. What it should do is, when spawned, get the location of target. Then get “shot up” and then move towards target location in parabola-like manner.

I can’t get it to work. The first part works pretty okay-ish, im quite happy with it. It moves up and towards the target in nice manner.

BUT, after it reaches the “first half” of parabola nad has to move DOWN, well… I dont know how to do it.

ill paste code down bellow.

//NOTE: you are more than welcome to post ideas for the first part of parabola-like movement, as well as my scripting in general too. I KNOW that my method of doing this is stupid. Note that its only few weeks im playing with unity OR any code in general.

public class CannonBallScript : MonoBehaviour {
   
    public float speed = 10f;
    public GameObject particleOnCol;

    public Vector3 testVector;

    public Transform target;
    public Vector3 landingPos;
    private float landingPosX;
    private float landingPosZ;
    private float startingPosY;
    bool isInFirstStage = true;

    public void TrackTarget (Transform atarget) //grabs from turret.
    {
        target = atarget;
    }

    void Start ()
    {
        landingPos = target.transform.position;
        landingPosX = target.transform.position.x;
        landingPosZ = target.transform.position.z;
        startingPosY = transform.position.y;
        Invoke ("ChangeStage", 0.5f); //end of first half of parabola.

    }

    void Update ()
    {
        if (isInFirstStage == true) {
            GetPosStart ();
        }
        else
        {
            MoveToTarget ();
        }
    }

    void MoveToTarget () //falling part of the ball
    {
        transform.position = Vector3.MoveTowards (transform.position, landingPos, speed * Time.deltaTime);

        if (transform.position == landingPos)
        {
            print ("kaboom");
            Destroy (gameObject);
        }
    }

    void GetPosStart () //ball is going up.
    {
        Vector3 GetHere = new Vector3 (landingPosX, startingPosY + 30f, landingPosZ);
        transform.position = Vector3.MoveTowards (transform.position, GetHere, Time.deltaTime * speed);
    }

    void ChangeStage ()
    {
        isInFirstStage = false;
    }
}

Almost this exact same question came up the other day, here. @jugnu never replied to let us know how it worked out, but I stand by my suggestion.

And man, this must be a FAQ — in trying to dig that up, I found about a half-gazillion other people asking essentially the same thing. And about a quarter-gazillion got answers from me, which I don’t like nearly as well as my latest answer. Perhaps I should write it up as a blog post.

Anyway, please give that parabola equation a try, and let us know if it does the trick for you!

1 Like

Thanks for the reply, Joe. You really should make a buy-me–a-cup-of-coffee donation link bellow in your signature.

However, it seems that there are new things that i have never heard about before. Atan2, which i never heard of, and Quaternion, which still gives me total headaches. Im at work currently, i will surely dig deepr into the post you linked me to once im at home. I do feel, that i will have more questions, therefore, i will probably keep this post updated. :slight_smile:

2 Likes

Ehh, have to admit - math was not my favorite subject in school. I gaved up and just googled the code that i needed.

However, Joe, i want to ask you something. It was a tad hard for me to understand everything you linked me to.

What does the “k” stand for in the formula you provided? I might play with that a little >.<

And, in the code i found, i wanted to make a few modifications and whenver i delete the first line (the yield return new) my script starts acting weird o.O it shoots the ball, but the ball never lands. And it alwasy seems to go to 0, inf, 0 position.

Anyway, for those who have googled and ended up here… Here’s a cheat code (providing it cause it uses Deg2Rad and sin/cos stuff… eww:

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

    // Calculate distance to target
    float target_Distance = Vector3.Distance(transform.position, testVector);

    // Calculate the velocity needed to throw the object to the target at specified angle.
    float projectile_Velocity = target_Distance / (Mathf.Sin(2 * privateRotation * Mathf.Deg2Rad) / dragDown);

    // Extract the X  Y componenent of the velocity
    float Vx = Mathf.Sqrt(projectile_Velocity) * Mathf.Cos(privateRotation * Mathf.Deg2Rad);
    float Vy = Mathf.Sqrt(projectile_Velocity) * Mathf.Sin(privateRotation * Mathf.Deg2Rad);

    // Calculate flight time.
    float flightDuration = target_Distance / Vx;

    // Rotate projectile to face the target.
    transform.rotation = Quaternion.LookRotation(testVector - transform.position);

    float elapse_time = 0;

    while (elapse_time < flightDuration)
    {
        transform.Translate (0, (Vy - (dragDown * elapse_time)) * Time.deltaTime, Vx * Time.deltaTime);

        elapse_time += Time.deltaTime;

        yield return null;
    }
}

k stands for “constant,” and in this case it just controls how much arc you have.

And coroutines, yuck - I would not recommend them for a situation like this. But hey, if it works for you, that’s great!

Sounds like I really do need to write that blog post… Perhaps I can get to it later that week.

@JoeStrout , if you were to make a blog post explaining why you do something and just throw in the logic/explanation behind each line… I can’t say i would love you, cause i already do, but i think you would come a step closer to the day community builds a shrine for you :smile:

3 Likes

Heh, well I don’t think I need a shrine. A simple statue in the town square would suffice.

I’ve put this at the top of my list of topics to blog about, and I’ll get it done as soon as I get the chance.

2 Likes

OK, blog post achieved!

1 Like

@JoeStrout Respect you:)

1 Like

@JoeStrout 's blog post seems to have moved, I found it here: Luminary Apps : Blog

8 Likes

Hey all, if you came here looking for a way to add a parabola in 3D environment that works the same way as @JoeStrout 's 2D version, check the link below. I spent the last three hours looking for it (and most google searches led me to this current post), so just to save time:

This blog post is great and it works very well.
One question though: how would one make the object continue moving in a parabolic arc even after reaching the target?

1 Like