If you’ve got a player character in your game that derives its movement from a Rigidbody
or Rigidbody2D
component in Unity, and you write a script to make your camera follow it, you will likely see jittering in your camera movement.
Here’s an example:
You may think that this is the kind of problem that requires a galaxy brain fix, but it actually has a really simple solution. Just find the Rigidbody
component on your player character, and…
This should make your camera movement smooth as a hedgehog. Here’s a side-by-side comparison of the before and after for comparison:
As a side note, this works if you’re using a Rigidbody2D
too — it has the same Interpolate property that you can change.
Why does the jittery movement occur?
That’s the million dollar question, isn’t it? Well, the answer lies in the way Unity (and many other game engines) draws its frames and processes physics.
By default, Unity runs at a frame rate of about 60 — this means that in 1 second, you can expect Unity to draw Update()
time step or Main time step.
The Rigidbody
component (which is responsible for physics-related movement of objects), however, doesn’t update itself in tandem with the Update()
time step. It updates itself instead in a separate update cycle with a fixed time step, which Unity calls the FixedUpdate()
time step or Physics time step. By default, the Physics time step happens in constant intervals of 0.02 seconds, or exactly 50 times a second.
As our player character’s motion is controlled by a Rigidbody
, it’s position is updated in the Physics time step. However, because Physics time steps do not update the frame, we are only shown the results of this update when the Main time step updates.
In other words, whenever our camera retrieves the position of our character to calculate where it should move towards, it is retrieving information from the nearest Physics time step, which is also slightly outdated.
Article continues after the advertisement:
Notice that this is problematic for a few reasons:
- Unless a Physics time step happens at the same time as a Main time step, the position of a
Rigidbody
is always slightly outdated when it is drawn by the Main time step. - Because the Main time step happens more frequently, there can be instances where the Main time step goes through a few updates without the Physics time step having a single update. This means that there may be consecutive frames where an object’s position does not update at all, as pictured below.
All of this causes the movement of the player character to be inconsistent every frame; and since the camera follows the player’s position, this causes the camera’s movement too be inconsistent too — hence the jittery nature of it.
Why does the fix work?
The Interpolate property works to fix this because it helps to “fill in” the gaps between Physics frames by estimating or predicting the position:
The Extrapolate option works slightly differently from Interpolate — one tries to predict the future position based on past data, while the other delays the Main time step by 1 frame to have 2 Physics frames to work with. To learn more details about how these options work, as well as how they work differently, check out the article linked below:
Does synchronising the time steps work?
Since we have the capability of changing both the frame rate (i.e. Main time step) and the fixed time step (i.e. Physics time step), we can actually decrease the frame rate or increase the frequency of the fixed time step. This isn’t a good fix to the problem, however, because the Main time step interval is inherently inconsistent — Unity tries to keep the frame rate at 60, but it isn’t always successful at doing that. This becomes obvious if you just print the Time.deltaTime
property in any Update()
function on a script.
void Update() {
// Time.deltaTime is the time between the previous frame and the current frame.
Debug.Log("Time.deltaTime: " + Time.deltaTime);
}
Hence, even if the frame rate is set to be the same as the Physics time step (which always maintains the exact same frame rate), the frames will not always be synchronised, and jitters can still occur.
That being said, it does improve the situation a lot, even though there is still somewhat of a jitter.
Turning on Interpolate still looks smoother though:
Article continues after the advertisement:
Thank you
Hi, awesome article!
“If you’re following a rigidbody that’s using interpolation, make sure you’re referencing rigidbody.transform.position and rigidbody.transform.rotation instead of rigidbody.position and rigidbody.rotation. The transform’s position/rotation is what gets interpolated, and the rigidbody.position and rigidbody.rotation will only update at the physics timestep (i.e. in FixedUpdate).”
Would you agree with this statement?
from https://forum.unity.com/threads/camera-following-rigidbody.171343/
Hi Edward, I’ve never considered this before, but I think the statement has a typo. He is probably saying to use
transform.position
/transform.rotation
overrigidbody.transform.position
andrigidbody.transform.rotation
; because he also says the “transform’s position/rotation is what gets interpolated”.What he is saying is to avoid using
rigidbody.transform.position
/rotation
to move the camera.Thanks for bringing this up. It is an interesting observation.
In the last section of the article, it states: ‘This isn’t a good fix to the problem, however, because the Main time step interval is inherently consistent’ I believe this is a mistake and is meant to say ‘inherently inconsistent’
Hi George, it is rude to point out mistakes in other people’s work~
Just kidding. Appreciate you pointing this out! We have updated the article.
great article, I ran into this issue myself just now and am glad I found this!
Hi Arvs, glad to know it helped!