• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
48
Question by picobots · Jun 26, 2012 at 07:40 PM · updatefixedupdatemotion

Update/FixedUpdate motion stutter (Note: This is NOT a novice deltaTime question)


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

Comment
Add comment · Show 39
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · Jun 26, 2012 at 08:02 PM 1
Share

Do you have pro? Have you tried looking at the profiler for spikes? Garbage Collection hit perhaps? Or is it all too simple for that ?

avatar image AchillesWF · Jun 26, 2012 at 08:12 PM 1
Share

It may be garbage collection hit - try having a single global or static Vector3 that is only instantiated once and then copy the transform position into it, modify it, and then set it back to the transform. Each of your cases you are allocating a new Vector3 every frame.

avatar image AchillesWF · Jun 26, 2012 at 09:18 PM 2
Share

Perhaps the problem is the fast frame rate of the scene when locked to VSYNC is such that we occasionally run too far ahead of the GPU and must occasionally wait (in the engine). It may be that a more complex scene would not stutter like this simple one does. I haven't tried accessing synchronization functionality in Unity yet, but perhaps you could introduce your own frame rate limiting system to make sure the game is running at 60 fps (and not artificially capped at 60 fps by vsync waits). If Unity is double buffered, or triple buffered internally it is still the case that submitting such a simple scene so quickly could cause the CPU to race ahead and need to throttle occasionally.

avatar image whydoidoit · Jun 26, 2012 at 09:39 PM 1
Share

@mortoc - no even that wastes a Vector3 doesn't it? The one that used to be the transform.position before _targetPosition was copied into it (being a value type it's copied and the old one discarded right?)

avatar image shmomo · Apr 22, 2013 at 02:56 PM 2
Share

Hi,

I submitted this as a bug report and the result was:

"I've been looking and this seems to be a pretty fundamental problem with the OSX web player.

As you surmised, it's related to frame-rates, although not specifically to FPS capping. The jitter comes from several different interactions between our web player's ti$$anonymous$$g code, the browser's plugin handler, and the graphics drivers.

Properly fixing the issue could take a few weeks, or even longer. Once a fix is found, the changes would have to go through our release process, so it's impossible to predict a resolution date.

I understand that this really sucks. To help you try to work around this, I took some tools from this thread: http://forum.unity3d.com/threads/162694-Smooth$$anonymous$$ovementTest-should-help-eli$$anonymous$$ate-Hiccup-sources

After some fiddling, I found that turning off vsync and setting a framerate of 61 FPS seemed to $$anonymous$$imize the issue for me. However, the issue is heavily dependent on hardware, OS and browser - what smooths things out on OSX/Chrome may make it worse on Windows/Firefox."

Show more comments

16 Replies

· Add your reply
  • Sort: 
avatar image
24
Best Answer

Answer by Wolfram · Jun 26, 2012 at 11:01 PM

As @Eric5h5 mentions in the forum thread, you will unavoidably create stutter when doing transformations in FixedUpdate(): FixedUpdate is framerate independent, and therefore completely unrelated to your framerate. The stutter will be most visible the closer your framerate comes to the actual physics/fixed time step (Note as Time.deltaTime is identical to Time.fixedDeltaTime in FixedUpdate(), and the latter's default is 0.02, your examples 2 and 3 will be absolutely identical), because it will create an "interference pattern" between the different call intervals - the one being a fixed time interval, the other being a not-so-fixed number-of-frames interval, which might well mean that there are two or three consecutive frames rendered without any FixedUpdate() called inbetween, even with VSync enabled, or sometimes two consecutive FixedUpdate() calls without a call to Update(), if there was some reason that rendering got delayed.

Concerning the stutter when using Update: Time.deltaTime is not perfect. In addition, it will contain the time the previous frame took to render, since the current time is of course unknown. So there might arise discrepancies from that, which unfortunately result in visible stutter (which is of course least visible at very high framerates with VSync off). So for example, you have a very smooth constant framerate with say Time.deltaTime==0.01, 100fps. For some reason (task switching, background process, stupid Windows OS programming), your graphics card has a hiccup, and the current frame is delayed by a few ms. Time.deltaTime for that fram will still be 0.01, but the frame takes longer to display, so your object lags behind. Entering Update() again, Time.deltaTime now contains the larger framtime of the previous frame, so you will create a larger motion. But your actual rendering time may have returned to normal. so your object jumps ahead. I don't think there is really anything you can do against that - not in Unity, and probably not outside Unity, unless you have 100% control of your GPU process management so that you can predict the rendering time of a frame with absolute certainty.

Note there also is Time.smoothDeltaTime, which is supposed to be a smoothed version of Time.deltaTime. Maybe it will have better behaviour in your case. But IIRC the results were usually worse, since then the frame time is averaged by some formula, so the frame time will even less realisticly represent your actual frame time for any particular frame.

Also note that there is Application.targetFrameRate, which might help you in your experiments by trying to enforce a certain framerate (it will propbably not resolve any stuttering issues, though).

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Wolfram · Jun 26, 2012 at 11:57 PM 0
Share

If you are experiencing regular hiccups (for example, each second), check your other running stuff: a clock widget would spring to $$anonymous$$d. Or even a Windows Task $$anonymous$$anager with the "Process" tab open. It took us a while at some point in the past, figuring out that the task manager was causing regular hiccups, even when our app was running fullscreen and the task manager therefore was not visible.

avatar image picobots · Jun 27, 2012 at 12:14 AM 0
Share

This is amazing information, thank you. It seems like I'm basically out of luck. I'm still left wondering how all of these other game developers get their games to run perfectly smooth (even on my system!)... But I guess not everybody does. Two examples come immediately to $$anonymous$$d: Fez really stuttered on my Xbox, and the title screen of SophieH's game here (where the pink clouds are floating past) also exhibits the same stuttering behavior: http://www.sophiehoulden.com/games/UVP4/

Ah well, maybe I just need to deal with it :) Thanks again for your response.

avatar image picobots · Jun 27, 2012 at 12:17 AM 0
Share

Just saw your comment: That's also a great point. I still have to look into what other programs are running (@Bunny83 also mentioned that in his answer). I've rebooted a few times, but I'll try to dig a little deeper and kill every process I can.

avatar image Wolfram · Jun 27, 2012 at 12:37 AM 5
Share

I'm still left wondering how all of these other game developers get their games to run perfectly smooth

Remember it will very much depend on the type of motion, as @Bunny83 explained: some examples that shouldn't show any noticeable stuttering (which doesn't necessarily mean that there is no stuttering!) include a rolling ball that slowly comes to a stop, a walking character, a panning 3rd person camera, or leaves and twigs bending in the wind. As these are all non-linear motions, your brain will be much less sensitive to any inconsistencies in the movement. On the other hand stuttering in moving clouds, a slowly driving car, or other types of linear motions will be much more noticeable, especially since there is a (relatively fixed, but marginally fluctuating) "constant" ratio between animation progression and framerate.

It would be interesting if you see games/game engines that do not generate stuttering linear animations.

avatar image picobots · Jun 27, 2012 at 12:54 AM 0
Share

@Wolfram: That's an excellent point. Hmm... Well, one that springs to $$anonymous$$d that I played recently (which is excellent by the way!): Home by Benja$$anonymous$$ Rivers ( http://homehorror.com ). I'm not sure what he used to develop it, but it's a side-scroller and there are no blips or hiccups in the motion at all. (Just reconfirmed.) $$anonymous$$aybe I'll have to e-mail him to ask him about it :)

Show more comments
avatar image
11

Answer by Bunny83 · Jun 26, 2012 at 11:13 PM

First of all, no, local value type variables are placed on the stack, not on the heap. The GC is only relevant for the heap memory. All memory for local variables are allocated when you enter a function and removed when you leave it. All those is placed sequential on the stack. The GC only cares about references. Value types are never GC collected. Note: an array for example is a reference type even when it contains value types.

When i run your little test project i can't see any hiccup on Update or LateUpdate (which is essential the same since it runs at the exact same rate with the exact same deltaTime).

FixedUpdate can cause visual fluctuations in the movement speed since it runs probably at a different rate than your visual update (the Update function).

FixedUpdate is ment to have accelerated movement to always behave the same way, so it's caluclated mathematically the same way. Linear movement can be lineary scaled with Time.deltaTime, but any polynomial function with a degree higher than 1 can't be made frame-independent by scaling it linearly with Time.deltaTime. That's what FixedUpdate is good for. It is executed a fix amount of times per second. This ensures that the calculations come to the same result, no matter on which machine it's executed.

FixedUpdate is ment for more complicated physics calculations. You won't see a hiccup in an accelerated movement.

That's why you usually use Update for almost everything. Update(and LateUpdate) is called before every visual frame. Note that if vsync is off, a visual frame might not be seen by you because the monitor isn't fast enough. The image is produced, but not displayed. Usually there's no reason to run without vsync.

So my advise is:

  • Use Update for linear movement

  • Use FixedUpdate for any accelerated or higher order calculations that depends on a constant rate.

ps: If you see hiccups in your Unity app, it doesn't need to be Unity that is producing those. Do you have any additional plugins active (flash[including youtube & co], acrobat reader, ...), maybe in another tab? I've seen a lot influence from other applications / browser-plugins. Even some websites have crazy javascripts running in the background. Some are refreshing their content silently every few seconds...

pps: Time.deltaTime always returns the fix timestep when used in FixedUpdate, so if you haven't changed your physics-timestep in the project settings there should be no difference between 2 and 3. I can't see a difference ;)

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Wolfram · Jun 26, 2012 at 11:26 PM 2
Share

Why can't I give this more than one thumbs up? :o)

avatar image picobots · Jun 26, 2012 at 11:59 PM 0
Share

@Bunny83: Thanks for the response! Very helpful information. I also can't see a difference between 2 and 3, but I just wanted to be thorough :) So you don't see the hiccup in #1, even after letting a few cubes go by? Again, it's not constant; it's just an occasional hiccup that only occurs every 1-3 seconds. As far as I can tell, not everyone sees it on their system. It's smooth for some people and not for others. Just out of curiosity, what is your video card?

avatar image Bunny83 · Jun 27, 2012 at 03:16 AM 0
Share

@there$$anonymous$$: On this PC it's even a quite old NVidia GeForce 8600 GTS (256$$anonymous$$B) with two monitors ;). I still have FireFox 4.0 here and the plugin container is disabled since it causes a lot of trouble in the past. Don't know if it's better in the current version.

Have you tried a standalone build?

avatar image wirelessdreamer · Mar 25, 2018 at 12:26 AM 0
Share

Thank you for taking the time to answer this. I was doing my movement logic in fixed update, ins$$anonymous$$d of update, and it was causing me so many headaches. Only wish it hadn't taken me 6 hours to find your post :)

avatar image
5

Answer by AnomalusUndrdog · May 06, 2013 at 07:20 AM

One thing I noticed on my old 2008 laptop, if there's something selected in the scene (i.e. the inspector is showing something), the whole game lags, including cases of stuttering motion.

If the inspector is not showing anything, it increases framerate and neutralizes stuttering motion.

This doesn't happen on newer machines as far as I noticed (even when comparing the same version of Unity, on the same project).

Also if you have more than one scene/game view on display, that obviously slows down framerate as Unity has to draw more than one camera.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Suzuka91 · Jun 04, 2017 at 03:04 PM 0
Share

God... Thank you! I'm also using an old laptop, but I've never noticed that with older versions of Unity. I was turning crazy. Thanks again, you made my day!

avatar image dustin_pau1 · Oct 14, 2017 at 08:34 PM 0
Share

Thank you! I was testing the scene and the stats indicated 100+fps but the camera look was definitely jittery, but having nothing selected in scene view fixed it! Thanks again!

avatar image evantbyrne · Jun 03, 2018 at 10:05 PM 0
Share

Fast forward to 2018. Deselecting everything within Unity didn't fix the very noticeable jitter for me, but then I tried running a release build and that was completely smooth. I'm guessing it probably still has something to do the development tools.

avatar image
4

Answer by jankymidget · Jul 29, 2015 at 07:52 AM

I set QualitySettings.vSyncCount = 0; and my stutter problems were fixed. It defaulted to 1, and this introduced a periodic annoying stutter.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image LyleD · Aug 18, 2016 at 07:49 PM 0
Share

Thank you. Putting this in my player movement script helped smooth out the jumpiness issue.

void Start () { QualitySettings.vSyncCount = 0; } void Update () { var x = Input.GetAxis ("Horizontal") * Time.deltaTime * speed; transform.Translate (-x, 0, 0); }

avatar image Shadoninja · May 31, 2019 at 02:24 AM 0
Share

This is identical to turning vsync off entirely: https://docs.unity3d.com/ScriptReference/QualitySettings-vSyncCount.html

avatar image
4

Answer by Vystyk · Nov 01, 2015 at 01:28 PM

Whew, I finally solved this one for my game after searching everywhere with no luck. The issue for me was that my camera functions were in LateUpdate while my other things were happening in FixedUpdate. With this setup, the difference in the frame rates of these two functions caused lerps to stutter. If I moved my camera functions to FixedUpdate with everything else, then The stutter goes away but my camera functions would align themselves to look at the object's previous position. That's because even if all the forces have all been applied to your rigidbody's, their movement and new position isnt calculated until after FixedUpdate. That problem meant that if the object was moving very fast (its a space game) then the camera would lag behind and the object would go offscreen even with the camera set to LookAt the object in ghat same FixedUpdate method. The solution I came up with is to keep your camera updates in FixedUpdate and inside you camera's update functions, add the target's position to its velocity times delta time: Vector3 updatedPosition = object.GetComponent().position +object.GetComponent().velocity * Time.deltaTime; Then base all your camera's positions and LookAt's on thiz updated position. You don't have to change any frame rates or anything like that. One note though, I don't use Update or FixedUpdate on individual scripts, instead I use a single script to call designated update methods on all my other scripts so I can control the order in which things get updated.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image mostafa_berg · Jan 22, 2016 at 12:10 PM 0
Share

A managed model like yours is really a good solution, it's something unity was just talking about and you can already see huge improvements in the performance !, check it out here:

http://blogs.unity3d.com/2015/12/23/1k-update-calls/

avatar image usernameHed · Mar 12, 2021 at 11:21 AM 0
Share

This answer need more attention, I resolved this issue by using the same technique, after a LOT of trial and error

  • 1
  • 2
  • 3
  • 4
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

45 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Jumping randomly doesn't work 2 Answers

Checkibg Rigidbody2d and component problems 0 Answers

Fixedupdate rate stays at 90 instead of 60 1 Answer

Why is OnGUI called significantly more than Update and FixedUpdate? 4 Answers

So what's the deal with FixedUpdate? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges