The Problem
Why does the motion stutter in an incredibly simple Unity game? This is a problem that has been plaguing me for years in game development (not just in Unity, but in XNA as well). Please note that I have a solid understanding of Time.deltaTime; this isn’t the typical noob question about how to get smooth motion (although I’d love it if someone has an easy answer).
I’ve played around extensively with turning VSync on and off, and I’ve tried a hundred different variations and combinations of Update/FixedUpdate/LateUpdate code, and no matter what I do, I cannot achieve perfectly smooth motion in a simple Unity game. The closest I can get to smooth motion is using Update() with VSync OFF; with those settings, I get over 400fps and mostly smooth motion (not 100% perfect though).
Is there any way to get perfectly smooth motion in a Unity game? I’m trying to make a basic 2D game, and compared to old NES games (like Mario or Zelda), the motion in Unity is always jerky and never as smooth.
Example
Take a look at this sample game (Unity Web Player required):
http://s3.amazonaws.com/picobots/assets/unity/jerky-motion/JerkyMotion.html
VSync is ON, which locks the frame rate to ~60fps (synced to my monitor’s refresh rate, which is actually 59.xxx Hz).
This game has 10 cubes and 1 orthographic camera.
There are 4 different scripts that move the camera. Only 1 script is enabled at a time, and you can switch between them using your keyboard. All 4 scripts exhibit jerky motion to varying degrees.
Code
1. Update (using Time.deltaTime)
This is the smoothest of all four options (although it’s close between this and LateUpdate), but every 1-2 seconds there is a “hiccup” in the motion. You can see the motion stutter and the moving cubes pause/jump slightly. Note: You need an eagle eye to see this. Look closely!
void Update()
{
transform.position = new Vector3(
transform.position.x + (2f * Time.deltaTime),
transform.position.y,
transform.position.z
);
}
2. FixedUpdate (using Time.deltaTime)
The motion stutter is very apparent using FixedUpdate. Instead of smooth movement, I see an almost constant subtle jerkiness to the motion. The cubes wobble as they move.
void FixedUpdate()
{
transform.position = new Vector3(
transform.position.x + (2f * Time.deltaTime),
transform.position.y,
transform.position.z
);
}
3. FixedUpdate (using a static value)
Same problem as #2.
void FixedUpdate()
{
transform.position = new Vector3(
transform.position.x + 0.04f,
transform.position.y,
transform.position.z
);
}
4. LateUpdate (using Time.deltaTime)
Similar to #1.
void LateUpdate()
{
transform.position = new Vector3(
transform.position.x + (2f * Time.deltaTime),
transform.position.y,
transform.position.z
);
}
An Even Simpler Example
Some of the comments (rightly) expressed concern about memory allocations and garbage collection, so here’s an even simpler example project that also exhibits the problem (standalone PC or Mac application):
http://s3.amazonaws.com/picobots/assets/unity/jerky-motion/JerkyMotion.zip
10 cubes, 1 orthographic camera, 1 script (with absolutely no allocations).