need help with Vector3.Slerp

Hi,

I’m trying to move an object along an arc in 2D and thought the best way was to use Vector3.Slerp and disregard the z. I’m trying to follow the example shown here but it’s not working, the object simply stays stationary in one spot.

Here is my code:

guiBeans = new Dictionary<Vector3, Vector3>();

public void OnGUI()
{
        List<Vector3> keys = new List<Vector3>();
        foreach (Vector3 key in guiBeans.Keys)
        {
            keys.Add(key);
        }

        for (int i = 0; i < keys.Count; i++)
        {
            Debug.Log("KEY: " + keys[i]);
            Debug.Log("VALUE: " + guiBeans[keys[i]]);
            GUI.Label(new Rect(guiBeans[keys[i]].x, Screen.height - guiBeans[keys[i]].y, 96, 64), "", guiBean);
            Vector3 pos = keys[i];
            Vector3 target = new Vector3(Screen.width / 10, Screen.height / 1.2f);
            Vector3 centre = pos + target * 0.5f;
            centre -= new Vector3(1, 1, 0);
            Vector3 posRelCentre = pos - centre;
            Vector3 targetRelCentre = target - centre;
            guiBeans[keys[i]] = Vector3.Slerp(posRelCentre, targetRelCentre, Time.time);
            guiBeans[keys[i]] += centre;
        }
        keys.Clear();
}

Here is an example of what’s being logged:

KEY: (314.1, 414.6, 141.9)
VALUE: (314.1, 414.6, 141.9)
KEY: (314.1, 414.6, 141.9)
VALUE: (90.0, 502.5, 0.0)
KEY: (314.1, 414.6, 141.9)
VALUE: (90.0, 502.5, 0.0)
KEY: (314.1, 414.6, 141.9)
VALUE: (90.0, 502.5, 0.0)
etc etc…

My understanding is that the key should be the initial position of the object at the beginning of the slerp, and that the value should be the new position of the object each frame as the slerp does its thing. As you can see from the log, the value only changes the first time, then stays the same, which is why my object is stationary. I can see why the value never changes… because its doing the same calculation every frame with the same values. But looking at the example, I can’t see how that is any different.

Anyone able to point out what I’m doing wrong?

Time.time is the time since you started the game, so your code will perform the slerp during the first second of the game. If you do the slerp thing at some later point, the Slerp function will return a position that is just the target position, since the Time.time is already above 1 at that point.

You should probably pass a value to the Slerp function that is 0 when you want the slerp to start and 1 when you want it to stop.

If that’s not what the problem is, then I don’t know.

The use of Time.time in the interpolation examples provided in the documentation is misleading at best (IMO); very rarely is using Time.time as the interpolation parameter going to give you meaningful or useful results.

(I don’t know why Time.time is used in those examples, but it’s sure caused a lot of confusion…)

I have replaced Time.time with a value that increases from 0 to 1 over the length of time I want the slerp to perform. The good news is I now have movement, it’s just not moving on the arc that I want, but I think its just a matter of playing with values now to get it right.

Can I just confirm that slerp should work in 2D ignoring the z? As you can see I’m moving a GUI.Label object in OnGUI.

It should work ok as long at the vectors you are slerping from and to are not almost opposite each other. But if you need to cover all cases, you should not use Vector3.Slerp for interpolations that must happen in a specific plane.

What else would you use for moving an object along an arc in a specific plane?

I ended up scrapping the slerp and using the bezier curve equation found here. It’s working well :slight_smile:

Could this also be done by instantiating the transforms you want then having that prefab look at a target then transforming the Vector by those newly created points? I may have to switch over to bezier after a day like this.