Take my useful script - but help me improve it?

This script, automatically moves and rotates and objects through a serious of “steps” each with their own options like rotation, worldspace, smoothing, etc.

I am using the option for lerp or slerp to get a straight line between certain points, but a curved one for others.

It is working very well, here’s an example of a platform moving akin to a familiar SM64, with debug lines and trail renderer to show the path:95574-examp.png

Here is the script in full:

The problem, or thing I need help understanding:

The movement is “smoothed” between the steps, but with multiple steps, this results in a non-fluent motion, in the sense of, you can “tell” where the steps are, because it slows down to each one.
I threw in some other variables and booleans to play with the values I was using, but to no avail -
What’s the magic to slerping but with a fixed rate,i.e, not slowing down to each step?

Am I overthinking this?

You are using lerp wrong (at least for what you want to accomplish). Vector3.Lerp(a, b, .5) returns the point half way between a and b. But if you repeatedly do a = Vector3.Lerp(a, b, .5) you are repeatedly moving half way to b but never quite getting there.

Eventually you get close enough and this line in your code if (Vector3.Distance (movingObj.transform.localPosition, steps *.pos) <= .1f) causes you to move to the next point.*
What you should be doing is lerping from the previous point (not the objects current position) to the next point according to to t. So something like this:
movingObj.transform.localPosition = Vector3.Lerp (steps [i - 1].pos, steps .pos, t);
You’re going to have to watch out for when i == 0 because you will get an index out of bounds exception, but hopefully you get the idea.

You are actually slerping between the current object position (moving) and the next step position (fixed).

As your object move away from last step’s position, the distance to next step’s position decrease, so the slerping is actually “slowing down” the movement at each step.
If you want to have a constant speed, you need to slerp between fixed positions, on a time-based factor, e.g. between “current” step and next step based on step duration.

Here is an example that works with your script:

// The step we are currently "in"
public int currentStep = 0;
// The step we move to
public int nextStep = 1;
// Interpolation between currentStep and nextStep : 0 -> currentStep, 1 -> nextStep.
public float interpolationFactor = 0f;
// The time at the start of currentStep
public float startTime = 0f;
// Total duration of a step.
public float stepDuration = 1f;

In the Start() function, we need to initialize startTime:

void Start()
{
    speed = steps[0].speed;
    smooth = steps[0].smooth;
    worldSpace = steps[0].worldSpace;
    startTime = Time.time;
}

And then in the Update() function we do the slerping:

    void Update()
    {

        // Switch between steps based on time
        // Equivalent to your Next() function
        if (Time.time - startTime > stepDuration)
        {
            currentStep = nextStep;
            nextStep++;
            if (nextStep >= steps.Length)
                nextStep = 0;
            startTime = Time.time;
        }
        // Interpolate based on time
        interpolationFactor = ((Time.time - startTime) / stepDuration);
        // Slerp
        movingObj.transform.position = Vector3.Slerp(steps[currentStep].pos, steps[nextStep].pos, interpolationFactor);
        movingObj.transform.rotation = Quaternion.Slerp(Quaternion.Euler(steps[currentStep].rot), Quaternion.Euler(steps[nextStep].rot), interpolationFactor);
// [...]