Chaz Ashley
Chaz Ashley

Reputation: 409

Camera is following not smoothly

The camera is supposed to follow a 2D character, here is code

void LateUpdate ()
{
    var to = target.position;
    to.z = transform.position.z;
    var newPos = Vector3.Lerp(transform.position, to, speed * Time.deltaTime);
    transform.position = newPos;
    newPos.z = to.z;
    Debug.DrawRay(newPos, Vector3.up, Color.green, 5);
}

I also draw positions of the character and the camera.

Red lines are character's positions, and green lines are camera's positions

enter image description here

What do I do wrong?

UPDATE:

I've figured out something interesting. On the picture below green lines are positions of the Camera that is moved by Vector3.Lerp inside a LateUpdate method. Yellow lines are positions of the character that I set to the character's Rigidbody2D inside FixedUpdate method, and the red lines are positions of the character's transform as they seen from inside the camera's LateUpdate.

enter image description here

What I want to say is that the actual position of the character is driven by its Rigidbody2D component. By changing Rigidbody2D's "Interpolate" option we can get different results.

The problem is that even if I add to the Rigidbody2D's position the same value every FixedUpdate tick, the result isn't so consistent. Sometimes the distance between new and old position is bigger than it should be.

Add to that the we set position of the camera in the LateUpdate method, which has different update rate than FixedUpdate, so even if we set the new position to the character's transform, and not to the Rigidbody2D, the movement of the camere still won't be smooth, because speed of the character will be different every frame.

For now I have only one solution.

  1. Set the new position of the character to its transform, and not to the Rigidbody2D
  2. Change position of the camere in its FixedUpdate, and not in the LateUpdate.

Then the positions will look like this

enter image description here

But since position of the camera is set in the FixedUpdate, it won't be so smooth as it might be, and also i'm not sure whether collision detection of the character will work good, since we set its position directly to its transform.

Upvotes: 2

Views: 656

Answers (1)

Timothy Groote
Timothy Groote

Reputation: 8643

the problem could be coming from how you are using interpolation to determine how far to move the camera.

I don't know if Vector3.Lerp's behavior would be to extrapolate if the third parameter (its fraction) is higher than 1.0, but i suspect this could be the problem (specifically if there is a bit more time between frames, and speed * Time.DeltaTime becomes higher than 1.0)

A better way (eliminating the lerp) could be to do the interpolation of distance over speed and time yourself ;

void LateUpdate ()
{
    var to = target.position;
    to.z = transform.position.z;
    //you can just multiply a Vector3 with a float 
    //so we can do the interpolation maths ourselves like this :
    var distanceToMove = (to - transform.position) * speed * Time.deltaTime; 
    var newPos = transform.position + distanceToMove;
    transform.position = newPos;
    newPos.z = to.z;
    Debug.DrawRay(newPos, Vector3.up, Color.green, 5);
}

(if that got confusing, here is cleaned up version to make it more concise)

void LateUpdate ()
{
    var to = target.position;
    to.z = transform.position.z;
    transform.position += (to - transform.position) * speed * Time.deltaTime; ;
    Debug.DrawRay(transform.position, Vector3.up, Color.green, 5);
}

Upvotes: 1

Related Questions