My Lerp function only works one way but not the other way

72 Views Asked by At

I have a dynamic FOV and crouching script for my player which both use the Lerp function for smooth camera movement, but it only works for the increase in FOV and decrease in height. When the FOV and height return to normal, it just snaps back instantly rather than giving the smooth movement expected.

Crouching:

if (Input.GetKey(KeyCode.LeftControl))
        {
            characterController.height = Mathf.Lerp(characterController.height, 0.5f, 10f * Time.deltaTime);
            canRun = false;
            canJump = false;
            walkingSpeed = 2f;
        }

        else
        {
            characterController.height = Mathf.Lerp(characterController.height, 2.0f, 10f * Time.deltaTime);
            canRun = true;
            canJump = true;
            walkingSpeed = 4f;
        }

FOV:

if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D))
            {
                Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, 65f, 10f * Time.deltaTime);
            }

            else
            {
                Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, 60f, 10f * Time.deltaTime);
            }

I've looked online but no one seems to be having this issue and the code looks like it should work. (I am new to this so it's probably something really obvious)

2

There are 2 best solutions below

0
KYL3R On BEST ANSWER

Code looks fine, also works fine. Tested the FOV here:

https://i.imgur.com/Wo6a0hP.mp4

You probably have another script manipulating the FOV, causing it to snap back immediately.

6
Jay On

If you want to lerp between two states, you would be best to store the lerp value as it's state is what determines the camera's position.

if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D))
{
    lerpValue = Mathf.Clamp01(lerpValue + (speed * Time.deltaTime))
}
else
{
    lerpValue = Mathf.Clamp01(lerpValue - (speed * Time.deltaTime))
}

Then use this value to perform your easing. I'm using smoothstep here instead of using a variable as a lerp minimum.

Camera.main.fieldOfView = Mathf.SmoothStep(60, 65, lerpValue);

Using a variable as the minimum like x = Lerp(x, 10, t); can really lead to some weird behaviour... imagine you have a framerate dip and delta time is ever 1.2s... what would happen? I very much don't recommend doing it this way and using tweeining function instead. Check out https://easings.net

This should ease your camera's fov without snapping. The same can be used for crouching.