Can't get lerping of camera positions to work properly

I'm using a modified version of the OrbitCamera from the 3rd person platformer tutorial. I'm trying to achieve a lock-on effect where the camera orbits around the player by default, but if you look at an object tagged enemy and tap the right mouse button, the camera position switches to the position of an empty gameobject positioned behind the player's shoulder called lockOnPos, and the camera rotation is locked to the player rotation. If you click the right mouse button again, you unlock, and it goes back to the orbit camera.

As you'll see in my code, I achieved this by using a coroutine to constantly poll whether or not "lockOnToggle" is true, and I toggle it by the Fire2 button (right mouse). If it is true, in Update, I cache the position of the camera as it was in orbit in a variable called prevCamPos, then switch the camera position to the position of the lockOnPos object, and lock the camera rotation to the player object. Otherwise, I check to see if prevCamPos was set in the previous update, and if it was, set the camera position back to prevCamPos, and then do the normal OrbitCamera stuff.

This works fine, but I don't like the way it snaps immediately, so I tried lerping the camera positions when I do the switches, and its completely jittery and weird, and I can't figure out why.

Anyway, here's the bulk of my code:

function Update () {
if (player) {

    if(lockOnToggle == true)
            prevCamPos = transform.position;
            transform.position = lockOnPos.position;
            transform.rotation = player.rotation;

        x += Input.GetAxis("Mouse X") * xSpeed * 0.02;
        y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;

        y = ClampAngle(y, yMinLimit, yMaxLimit);

        var rotation = Quaternion.Euler(y, x, 0);
        var targetPos = player.position + targetOffset;
        var direction = rotation * -Vector3.forward;

        var targetDistance = AdjustLineOfSight(targetPos, direction);
        currentDistance = Mathf.SmoothDamp(currentDistance, targetDistance, distanceVelocity, closerSnapLag * .3);

        transform.rotation = rotation;
        newCamPos= targetPos + direction * currentDistance;

        if(prevCamPos ==
            transform.position = newCamPos;
            LerpPosition(0.5, prevCamPos, newCamPos);
            prevCamPos =;



function LerpPosition(time : float, prevPos : Vector3, newPos : Vector3) { var originalTime = time;

while (time > 0.0)
    time -= Time.deltaTime;
    transform.position = Vector3.Lerp(newPos, prevPos, time / originalTime);


Any idea what I'm doing wrong?

Currently your camera's previous position variable "prevCamPosprevCamPos" is set to the transform it was then. This is an absolute position. So if your character would move it and release lock to old form you would go back to that ABSOLUTE position instead of the relative position from the main character.

This point of origin is also the one you want to use for a Linear Interpolation (LERP), maybe the problem is the relative position and the calculation of the curve. That's just a wild speculation on my behalf though. You can quickly test this to see if there is difference when u move or not. If there is no difference it does not matter.

Perhaps what u need instead is a bad call or LERP, what is that time variable and how can it stop being called?

It could be something as simple as the LERP steps [Domain] simply being set to to high a value or that the camera is changing the lookAt spradically during the process.

I'm not sure this is even remotely a good answer, but idea's don't ever happen in White Space :)