Fixing a jittery camera in Unity
Screenshot from Cobalt Blue, a game currently in development.

Fix jittery camera movement in Unity with Rigidbody Interpolate

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:

Camera jitter in Unity
It’s not very noticeable if you don’t move at high speeds.

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…

Unity Rigidbody's Interpolate
Change the Interpolate property from None to either Interpolate or Extrapolate.

This should make your camera movement smooth as a hedgehog. Here’s a side-by-side comparison of the before and after for comparison:

Camera jitter in Unity
Camera jitter in Unity, fixed

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 appromixately 60 frames. This also means that, in the case of our running player character, Unity updates his position roughly 60 times a second. This can be called the 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.

Unity frame rate vs. Physics frame rate
Physics (i.e. FixedUpdate()) time steps are always constant, whereas the Main Update() time steps are not.

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.

No interpolation in a Rigidbody
If Interpolate is set to None, a Rigidbody‘s position will be determined by the nearest Physics time step.

Article continues after the advertisement:

Notice that this is problematic for a few reasons:

  1. 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.
  2. 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.
Unity frame rate lines, same Physics frame
In such a case, an object will maintain the same position across 2 Update() frames.

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:

Interpolate graphic explanation
Extrapolation explanation with timeline

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);
Time.deltaTime values in Unity
Time.deltaTime is never consistent, which means the frame rate is never constant.

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.

Camera jitter in Unity after frame rate sync
With Main frame rate and Physics frame rate set to 50.
Camera jitter in Unity
With Main frame rate at 60 and Physics frame at 50.

Turning on Interpolate still looks smoother though:

Camera jitter in Unity after frame rate sync
Without Interpolate.
Camera jitter in Unity, fixed
With Interpolate.

Article continues after the advertisement:

There are 7 comments:

  1. 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?


    1. 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 over rigidbody.transform.position and rigidbody.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.

  2. 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’

    1. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Note: You can use Markdown to format your comments.

For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

I agree to these terms.

This site uses Akismet to reduce spam. Learn how your comment data is processed.