0
\$\begingroup\$

In my Unity 2D platformer, I'm trying to move the camera down a bit when the character is crouching but not moving. I've done this with the following:

cameraPosition = mainCamera.transform.position.y;
cameraPosition = Mathf.Lerp(cameraPosition, cameraPosition - 0.8f, 3 * Time.deltaTime);
mainCamera.transform.position = new Vector3(mainCamera.transform.position.x, cameraPosition, mainCamera.transform.position.z);

This works, but it's causing the camera's y value to decrease continuously rather than just 0.8f, because cameraPosition is assigned a new value every frame. But cameraPosition has to be relative because its location depends on the player's location, so I can't figure out how else to write it.

\$\endgroup\$
1
  • \$\begingroup\$ Lerp(A,B,C) returns the interpolated value placed at (C*100) percents between A and B (in that order) If you use what you wrote every frame this is what happen : CameraPosition gets incremented, and then that incremented value is passed (in the next frame) as parameter to the next frame incrementation. Lets admit that instead of Time.time you used 1, you would get : CameraPosition = CameraPosition +0.8F; every frame (Looks familiar?) Whatever the value of C because A = Lerp(A,A+x,C), A always increase \$\endgroup\$ Commented Mar 26, 2015 at 16:05

2 Answers 2

1
\$\begingroup\$

The turn my comment up there to an answer :

The "proper" way to use Lerp in your case would be that :

Vector3 originalCameraPosition;
bool hasBeenSet = false;
public void OffsetCamera() { //Call that every Frame

    if(!hasBeenSet ) originalCameraPosition = cameraPosition;
    cameraPosition = Mathf.Lerp(originalCameraPosition , originalCameraPosition - 0.8f, 3 * Time.deltaTime);

}

Copying my comment up there on why you do not get the proper result your way :

Lerp(A,B,C) returns the interpolated value placed at (C*100) percents between A and B (in that order)

If you use what you wrote every frame this is what happen :

CameraPosition gets incremented, and then that incremented value is passed (in the next frame) as parameter to the next frame incrementation.

Lets admit that instead of Time.time you used 1, you would get : CameraPosition = CameraPosition +0.8F; every frame (Looks familiar?) Whatever the value of C because A = Lerp(A,A+x,C), A always increase!

\$\endgroup\$
0
\$\begingroup\$

It seems like what you want is a camera target attached to the character as a child, which your camera will continuously move to look at. When your character ducks, you'll move the target a certain amount relative to the character, instead of the camera itself.

Also, rather than lerping I would suggest using SmoothDamp to align the camera a fixed distance away. Just tweak the settings until your damping is right.

Then. within your camera's follow behavior, something like:

public Vector3 FollowDistance = new Vector3(0,0,10);
public GameObject Target;
public float SmoothTime = 0.3f;

private Vector3 _velocty;

void Update() {
    var cameraDestination = Target.Transform.Position - FollowDistance;
    transform.position = Vector3.SmoothDamp(transform.position,
                                            cameraDestination,
                                            ref _velocity,
                                            SmoothTime);
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .