# How to 2D Camera follow with lag.

I’ve tried to get this code working, I know it should be simple, but apparently I can’t wrap my head around it. So any guidance would be nice.

My situation is kind of like a infinite runner/2d platformer and the character is rigidbody2D driven.
Basically what I’m trying to do is have the camera follow the Character but with a lag time of catching up…
For example, let’s say the character is running at a constant speed of 5. During this time the character would be at the same position in the camera view and only the environment would look like their moving.
Now the character accelerates to a speed of 10, I want the character to move forward relative to the character in screen position and a few seconds later the camera would catch up to the character going at the speed of 10 and bring him back to the original character screen position.

## Animating the Camera

To achieve what you want, you need to animate the camera position. You’ll find next a code example and explanation of this code.

## What the code do

In this code, we assume that the camera is a children of the character that you are following.

When we call the StartLag function we’re telling the code to start animating an offset on the camera position. The animation will take `lagDuration` (in this example, 2 seconde) to play the lag. The camara will be move base on the `offset` vector (-5 unit back on the X axis).

## SmoothStep

For animating, we use the `Mathf.SmoothStep` function. Here the description:

This function interpolates between min and max in a similar way to Lerp. However, the interpolation will gradually speed up from the start and slow down toward the end. This is useful for creating natural-looking animation, fading and other transitions.

We’ll use that function 2 time:

1. FROM original position TO offset position
2. FROM offset position TO original position

## `lagPeak`

You’ll probably want to reach the offset position quicker than it take to come back to the original position. `lagPeak` allow you that. To calculate the time it take to reach the peak, multiply `lagPeak` and `lagDuration`. Here an example of what it mean:

• If `lagDuration == 2f` and `lagPeak == 0.5f`, the camera will reach is offset in 1 second and come back in 1 second.
• If `lagDuration == 2f` and `lagPeak == 0.1f`, the camera will reach is offset in 0.2 second and come back in 1.8 second.

## Code Example

``````//Public Interface. Tweak these value to change the result.
[Range (0,1)] public float lagPeak = 0.5f;
public float lagDuration = 2.0f;
public Vector3 offset = new Vector3(-5,0,0);

//Internal variable (not to modify)
private float movementTimeStart = 0.0f;
private bool isLagin = false

///Initialize Lag animation value
void StartLag()
{

isLagin = true;
movementTimeStart = Time.time;
Vector3 camInitialPosition = this.transform.localPosition
Vector3 camOffsetPosition = camInitialPosition - offset;
}

void Update()
{
AnimateLag();
}

///Animate the Lag
void AnimateLag()
{
float t;
//If the animation duration is invalid, jump to the end. (Prevent dividing by 0)
if (lagDuration <= 0.0f)
{
t = 1;
}
else
{
//Calculate the pourcentage of the animation
t = (Time.time - movementTimeStart) / lagDuration;
}

//Animate the piece
//
// The animation is separete in 2 part, Reaching the peak and comming back.
// To adjust the peak timing, we use the lagPeak variable that represent when (in %) the peak should be reach
if(t < lagPeak)
{
this.transform.localPosition = new Vector3 (Mathf.SmoothStep (camInitialPosition.x, camOffsetPosition.x, (t * (1/lagPeak))),
Mathf.SmoothStep (camInitialPosition.y, camOffsetPosition.y, (t * (1/lagPeak))),
Mathf.SmoothStep (camInitialPosition.z, camOffsetPosition.z, (t * (1/lagPeak)));
}
else
{
this.transform.localPosition = new Vector3 (Mathf.SmoothStep (camOffsetPosition.x, camInitialPosition.x, (t * (1/(lagPeak-1)))),
Mathf.SmoothStep (camOffsetPosition.y, camInitialPosition.y, (t * (1/(lagPeak-1)))),
Mathf.SmoothStep (camOffsetPosition.z, camInitialPosition.z, (t * (1/(lagPeak-1))));
}

//If we have finish
if (t >= 1)
{
//Reset Animation data
isMoving = false;
movementTimeStart = 0.0f;
camInitialPosition = Vector2.zero;
camOffsetPosition = Vector2.zero;
lagDuration = 0.0f;
}
}
``````

For more code explaination, just comment.