local Lerp possible?

Hi guys,

I want to use a lerp to move from one position to another, which is easy enough. I want to do it from the local transform though… So it only moves locally to itself… I know you can do transform.right * fWhatever… But that wont actually lerp an exact position for me. It’ll just move it sideways…

I want to move it exactly from one local position to another. Global wont work in this instance.

Can anyone advise???

Thanks

I’m trying to understand what you’re looking for, and why Vector3.Lerp wouldn’t work with localPosition. You’d input localPosition coordinates and lerp works fine between them.

The main thing is that you can’t mix localPositions and world positions. If you need to convert between them, there are the TransformPoint and InverseTransformPoint functions to use.

Do you have example code of what doesn’t work?

Vector3 startLocalPosition = new Vector3(-10, 0, 0);
Vector3 endLocalPosition = new Vector3(10, 0, 0);
transform.localPosition = Vector3.Lerp(startLocalPosition, endLocalPosition, 0.5f);

You can do this with matrices via Transform.worldToLocalMatrix, though Unity has no built-in matrix interpolation function. It’s much easier to perform this animation by interpolating quaternions and vectors. You can do that Quaternion.RotateAround() and transform.localPosition and transform.localRotation. You can certainly use these for the sake of simplicity. But, here’s the fun way to do it…

To find a child object’s local transform relative to its parent, take the inverse of the parent’s world transform by the child’s world transform.

World to Local Orientation (Q’s are quaternions):
Qchildlocal = Q-1parentworld * Qchildworld

World to Local Position (v’s are position vectors):
vchildlocal = Q-1parentworld * (vchildworld - vparentworld)

You also need the inverse transforms to get back to World space, which is done by taking these equations and solving for Qchildworld and vchildworld:

Local to World Orientation:
Qchildworld = Qparentworld * Qchildlocal

Local to World position:
vchildworld = Qparentworld * vchildlocal + vparentworld

C#

void GetLocalRotationPosition(Transform child, out Quaternion localRotation, out Vector3 localPosition)
{
    Quaternion qi = Quaternion.Inverse(child.parent.rotation);
    localRotation = qi * child.rotation;
    localPosition = qi * (child.position - child.parent.position);
}

void SetLocalRotationPosition(Transform child, Quaternion localRotation, Vector3 localPosition)
{
    Quaternion qi = Quaternion.Inverse(child.parent.rotation);
    child.rotation = child.parent.rotation * localRotation;
    child.position = child.parent.rotation * localPosition + child.parent.position;
}

Here’s a quickie example. I wrote a small coroutine test, and it appears to work well.

IEnumerator LocalLerp(Transform from, Transform to, float duration)
{
    Quaternion q1, q2;
    Vector3 v1, v2;

    GetLocalRotationPosition(from, out q1, out v1);
    GetLocalRotationPosition(to, out q2, out v2);

    float dt = 0;
    while (dt <= duration)
    {
        Quaternion q3 = Quaternion.Slerp(q1, q2, dt);
        Vector3 v3 = Vector3.Lerp(p1, p2, dt);
        SetLocalRotationPosition(from, q3, v3);
        dt += Time.deltaTime / duration;
        yield return null;
    }
}

You can add some vectors from a starting position multiplied by a value between 0 1 to interpolate between the two. The object you are moving as well as the two points should be a child of the same object and not eachother, or you can just manually write the vector positions.

public Transform start_point;
public Transform end_point;
public float point_amount = 0.0f;

void Update(){
    point_amount = Mathf.Clamp(point_amount, 0.0f, 1.0f);
    transform.localPosition = start_point.localPosition + (point_end.localPosition - point_start.localPosition) * point_amount;
}

This may just be a more complex way of writing Vector3.Lerp(…) though.

Use something like this

transform.localPosition = Vector3.Lerp(transform.localPosition, to.position, Time.deltaTime)

Dont worry, it will automatically convert the to.position co-ordinates to Local