Impossible to get perfectly smooth motion with Unity?

Why does the motion stutter in an incredibly simple Unity game when using a fixed time step? 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 with a fixed time step. 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, but I also get some screen tearing (and the motion still isn't perfectly smooth, even with VSync off).

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 Game

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
    );
}
  1. 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
    );
}
  1. 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
    );
}
  1. 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
    );
}
2 Likes

FixedUpdate is only for physics. Since it doesn't run at the screen refresh rate, you wouldn't be able to get smooth motion by moving things in code using transform.position. (By the way, using Translate would be simpler.) For physics, you can apply forces and turn interpolation/extrapolation on instead. I'm not sure about the webplayer, which may or may not respect vsync, but using vsync for a standalone does in fact produce perfectly smooth movement via Update here.

--Eric

2 Likes

Thanks for the response, Eric!

Unfortunately, I do see this problem in a standalone app via Update(). The stutter problem looks exactly like it does in the Web Player. (Confirmed on multiple systems. Two different PCs, one Mac.)

I posted the same question on Unity Answers, and other users see the stuttering too. We're investigating if it's a garbage collection issue: http://answers.unity3d.com/questions/275016/updatefixedupdate-motion-stutter-not-another-novic.html

I created an even simpler project, and I still see the stuttering issue:

http://s3.amazonaws.com/picobots/assets/unity/jerky-motion/JerkyMotion.zip

(210.1 KB)

  • Standalone app (Windows or Mac)
  • 10 cubes, default diffuse material
  • 1 orthographic camera
  • 1 super simple script attached to the camera (absolutely no allocation, garbage collection should not be an issue)

Every 1-2 seconds, there's a hiccup in the motion that causes the cubes to stutter/judder as the camera pans past.

It must be your scripts.
I run 30 times what you listed and have it running smooth on an iPad. Unity is a fantastic program.

Not seeing that here, sorry. (Mac Pro, ATI 5870.) There’s no memory allocated aside from 52 bytes/frame from Unity’s mouse polling, which will take a long time to trigger any garbage collection.

[quote=“picobots”, post:3, topic: 479805]
I posted the same question on Unity Answers
[/quote]

I’d appreciate it if you wouldn’t do that. Please use one site or the other; people (including me) have been burned too many times spending our time answering a question only to find that it had already been discussed/answered elsewhere, which turns “spending time” (which is fine) into “wasting time” (which I don’t enjoy at all), and it makes a coherent discussion difficult when it’s divided over two separate sites.

–Eric

1 Like

@renman3000: As linked in my second post, the project and scripts are ridiculously simple. There's only one script in the project, and it's basically impossible to write a simpler script to create motion. And I also love Unity. I've been using it happily for a year now, it's great.

It should also be noted: I don't see this issue on iPad or iPhone. I only see this problem with a fixed time step on PC and Mac, standalone or Web Player (PC #1: NIVIDIA GT880, PC #2: Intel integrated graphics, MacBook Pro: NVIDIA GT330M). At least two other users on Unity Answers also see the problem (both standalone and web player), so I'm not alone.

@Eric5h5: My apologies, I wasn't sure where the best place to post was. I'll keep my questions in Unity Answers going forward, thanks for the heads up.

Did you find a solution for the problem already?
We have the same issues with our side-scrolling game.
With v-Sync turned off the stuttering is least visible but it's still there.

Time.smoothDeltaTime also seems real unstable. (Core2Quatro 3.3 / 6Gb RAM / ATI 5830)

I think core problem in Environment.TickCount Int32.MaxValue if you try to collect and than log it you can see that many log strings are equal, time not changed between Update(), in that moment things start unstable moving.

I duno other time source but if it exists, you can try to count delta from it for you self.

I believe you need to smooth out FixedUpdate with Time.fixedDeltaTime (instead of Time.deltaTime)

1 Like

runs smooth on my machine and I have low specs win 7 32 bit intel express chipset g41. using Chrome browser

[quote=“carmine”, post:10, topic: 479805]
I believe you need to smooth out FixedUpdate with Time.fixedDeltaTime (instead of Time.deltaTime)
[/quote]
According to docs Time.deltaTime is the recommended use for both Update and FixedUpdate function calls as Time.deltaTime automatically returns the proper delta time in both update and fixed update functions.

http://docs.unity3d.com/Documentation/ScriptReference/Time-fixedDeltaTime.html

i really suspect that this has to do with the display used.
i also ran into this problem. testing it revealed the following:
i works well on the laptop display (60 hz) and it starts to jerk on the secondary display (59.9 hz).
it's even jerky when i start the standalone-game on my secondary display and then move the window to the laptop display.
and if i start it on the laptop display and then move it to the secondary display it's working without any stutter.
i tried the same game on a different laptop (without a secndary dispay) and it was quite smooth.
(all tested on a mac with osx 10.8)

best
jroge

The problem is cameras, You must have only one camera enabled in scene. first delete MainCamera in new project and use First person camera for your project

no it has nothing to do with cameras. it also happens with only one camera and a simple cube.

I always get stuttery motion in Unity when Vsync is on (even if the system is capable of rendering the scene at 600fps or something). I don't know what the the problem is, but I've just resolved to always turn Vsync off for PC and Mac.

On the other hand, looking at your examples, clearly you will get stuttery motion when moving in FixedUpdate. You are moving it by a discrete amount every fixed update cycle (which is normally far fewer times per second than your graphical frame rate), so you will see those discrete jumps.
To get smooth motion in FixedUpdate, move only using forces or rigidbody.velocity, and turn on Interpolation or Extrapolation on the rigidbody's settings. This will smooth the motion in graphical frames between fixed update frames.

[quote]
lease note that I have a solid understanding of Time.deltaTime; this isn't the typical noob question about how to get smooth motion
[/quote]

I apologize if I'm wrong here, but your code examples give us exactly the impression that you don't actually have an understanding of Fixed Update at all, and therefore this is a very typical noob question about how to get smooth motion.

Tested the scripts out like everybody else said the script runs fine on my machine as well as some android and iDevices.

[quote=“iWoundPwn”, post:17, topic: 479805]
Tested then scripts out like everybody else said the script runs fine on my machine as well. And as some android and iDevices.
[/quote]

Tested. Interestingly I get the same problem as him. Using the latest Unity 4. Reproduceable jerkiness on a new Unity 4 install too (in different clean computer. Both PC are

gaming rigs) and android tablet Asus TF700 JellyBean.

Time.deltaTime seems to be only reliable if I use Lerp routines for movement, but if using it in Update() for movement, it jerks the movement a lot ( around each 3-4 sec ish). VSync is off (for all quality settings), and also unless it goes more than 70 ish fps, it is quite noticable.

I don’t remember seeing this while using Unity 3.5.7 (I’ll reconfirm in a few days.)

Hey,

I don't know if you are suffering from the same thing I was but for me this was caused by a disparity between what different things thought my screen refresh was.

See http://forum.unity3d.com/threads/142754-linear-movement-stuttering

Hope that helps. If not then I hope you find the solution you are looking for!

EvilNoodle

Hi,

I'm seeing the same thing here, Macs, PCs, iPhone, and iPad. Everything from a high end Retina display Mac down to a crappy iPad 1. It's ugly, across the board.

Unity 4.1.2f1

I'm hopeful one of these other links will have a solution, and if I find it, I'll report back.

-Chilton