2

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.

7
  • Try SmoothCamera script from UnityWiki, you have to make changes to support only 2D follow (just set position along z axis constant). Here's the link : UnityWiki or UnityWikiCached Commented Aug 1, 2017 at 10:59
  • I tried simple script and the improved one, still has the problem, I think the problem is in something else, not in the code Commented Aug 1, 2017 at 11:28
  • Is it not smooth in device only or both Editor and device? Also try setting this in Awake of any script Application.targetFrameRate = 60; Commented Aug 1, 2017 at 11:33
  • it's not smooth in device and Editor as well, I set the frame rate but it didn't help Commented Aug 1, 2017 at 12:09
  • Try setting quality settings to Fantastic. If still same problem, try some other settings mentioned here forum.unity3d.com/threads/… Commented Aug 1, 2017 at 12:17

1 Answer 1

1

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); } 
Sign up to request clarification or add additional context in comments.

3 Comments

+1, This is not how lerp should be used. The third parameter is a percentage, you should never use delta time here. This example could probably be replaced with MoveTowards, but for a better camera effect I prefer SmoothDamp : Linear interpolation has a "boring" feeling.
welp, I tried both variants you guys have suggested, and it doesn't look like something has changed. I also use a value between 0 and 1 in the Vector3.Lerp function (something around 0.1), and I thought that using Time.deltaTime makes the speed of the camera movement independent from the frame rate
@ChazAshley using Time.DeltaTime will account for the differences in time it takes to render each frame, so that should remove fluctuations in speed along with the framerate. The use of Lerp in your code is somewhat dangerous because of how it performs the interpolation. From what i can see in your debug screenshot something goes wrong every 9 or so frames. Even though lateupdate is the recommended way of doing this, i am suspicious of it.Try and see if it still goes wrong when you move the code to update instead.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.