x


Throwing Object with acceleration equation/script?

I would like to script the animated movement of an object between two positions. So there is the start vector and the end vector. The start and end positions are important, and the trajectory should look something roughly like in the image below, but it shouldn't be too precise.

trajectory

Because the end position should be a fixed one, I can't really use rigidbody physics. I tried using Vector3.Slerp and Vector3.Lerp, but I couldn't manage to get an acceleration at the end of the trajectory curve.

Could you please give me a few hints, as I forgot the math behind these things?

Thanks a lot!

more ▼

asked Nov 26 '09 at 04:02 PM

BogdanDude gravatar image

BogdanDude
268 15 17 32

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

You're on the right track with Vector3.Lerp (but not Slerp - that's more for interpolating directional vectors rather than positions).

What you need is to just add a curve-based value to the object's height in addition to the straight-line interpolation that Lerp gives you. You can get a nice curved value range which goes from 0 to 1 and back to 0, by feeding a range from zero to PI into the Mathf.Sin function.

Here's a small c# example script which demonstrates:

using UnityEngine;
using System.Collections;

public class Trajectory : MonoBehaviour {

    Vector3 startPos = new Vector3(0, 0, 0);
    Vector3 endPos = new Vector3(0, 0, 10);
    float trajectoryHeight = 5;

    // Update is called once per frame
    void Update () {

        // calculate current time within our lerping time range
        float cTime = Time.time * 0.2f;

        // calculate straight-line lerp position:
        Vector3 currentPos = Vector3.Lerp(startPos, endPos, cTime);

        // add a value to Y, using Sine to give a curved trajectory in the Y direction
        currentPos.y += trajectoryHeight * Mathf.Sin(Mathf.Clamp01(cTime) * Mathf.PI);

        // finally assign the computed position to our gameObject:
        transform.position = currentPos;

    }
}
more ▼

answered Nov 26 '09 at 04:19 PM

duck gravatar image

duck ♦♦
41k 92 148 415

(comments are locked)
10|3000 characters needed characters left

Thanks a lot for your quick reply. In my case your code didn't really work. Using Time.time isn't the best idea (it would probably work only when you first hit play in the editor, as it accumulates)

Here's the code I used, which does pretty much what I wanted:

Vector3 targetPosition = target.position;



    float timerThrow = (object.position - targetPosition).magnitude;

    float cTime = timerThrow;
    Vector3 startPos = object.position;

    while ((object.position - targetPosition).sqrMagnitude > 0.01F)
    {

        cTime -= 0.4F;

        object.position = Vector3.Slerp(targetPosition, startPos, cTime / timerThrow);
        yield return 0;
    }

Because I added the distance between the 2 points in the equation (the magnitude), the animation has the same speed regardless of the distance between the 2 points. If you know any good way to optimize the above code, to run even faster, please let me know.

more ▼

answered Nov 26 '09 at 05:19 PM

BogdanDude gravatar image

BogdanDude
268 15 17 32

Yes, of course - Time.time was used an example, in the absence of knowing exactly when you want the animation to occur within your particular project. Sorry if I didn't make that clear. Other than that, it does exactly what you wanted though, right?

Nov 27 '09 at 01:08 PM duck ♦♦

A couple of notes about your script:

I'm interested in your use of 'Slerp' here - I think this will mean that your objects will be moved spherically around the world origin, which might cause problems if your start & end positions aren't evenly positioned either side of it.

Also, your 'while' loop is going to run at the same speed as Update() is called, which will vary across different computers - so rather than subtracting a fixed amount from 'cTime', you should be using Time.deltaTime to make sure that the movement completes at the same speed, irrespective of the frame rate.

Nov 27 '09 at 01:12 PM duck ♦♦

As for optimising the code, I would say that it needs no optimisation at all. This code is pretty optimal as-is.

Nov 27 '09 at 01:15 PM duck ♦♦

Yup, I forgot to take Time.deltaTime into consideration. I'll replace cTime -= 0.4F; with cTime -= Time.deltaTime * Constant; You were right about the Slerp too :) It only makes a round curve around the world origin (I tested it around that point). I'll use your approach. Thanks again!

Nov 27 '09 at 04:57 PM BogdanDude
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x5093
x1880

asked: Nov 26 '09 at 04:02 PM

Seen: 4910 times

Last Updated: Nov 26 '09 at 04:02 PM