When doing this in the Update, I get different results with different framerates.
When doing this in FixedUpdate Input.GetButtonDown sometimes returns false when it’s not supposed to.
The same question has been discussed here, but it seems like a very messy solution to keep track of all the input manually.
Most of the answers I’ve read on here say that polling input in FixedUpdate should never be done. This sample on the unity3d website does poll input in the FixedUpdate though;
I’m getting the best results in the Update right now. I might be able to get consistant results on different framerates when I apply deltatime. But I want to avoid applying physics in the Update where it doesn’t really belong.
This is a confusing and often misunderstood area. As a general rule:
Input should be in Update(), so that there is no chance of having a frame in which you miss the player input (which could happen if you placed it in FixedUpdate(), say).
Physics calculations should be in FixedUpdate(), so that they are consistent and synchronised with the global physics timestep of the game (by default 50 times per second).
Camera movement should be in LateUpdate(), so that it reflects the positions of any objects that may have moved in the current frame.
However, there are always exceptions to these, and some experimentation may be required to get what works for you in a given scenario.
tl;dr: FixedUpdate will be called 0…n times per frame. Update will be called once (after physics are updated) per rendered frame. For perfectly accurate input you should honestly check for input in both places. If you’re not trying to replicate the per pixel perfection of Mega Man X’s input and collision detection, then you’re perfectly safe putting everything in Update. Just know that you will be losing a frame of physics by doing so.
Do not let anyone tell you that not using FixedUpdate1 is a good idea. FixedUpdate is fired before physics calculations… this means that if you put your input code there, the player will see the reaction to the inputs on the SAME frame, not the next one. This becomes significant at low frame rates. (Especially consider 30 FPS capped mobile devices.)
Scenario One: You’ve created a game and want to have an NPC pacing left and right, up and down a flight of stairs. You’ve put your pacing code in Update and everything works perfectly… until your CPU is hit with a surge of other things to do from another process. Your FPS drops down to 2, even just for a moment, but it’s in that moment that your physics breaks down. If you’ve implemented your “ascend stairs” logic in Update using raycasting, you’ll notice that your NPC didn’t quite move the same way that they had been while your FPS was 60. This is because you’ve taken away Unity’s ability to give you accurate and “in reaction to” physics events (OnCollision*).
Scenario Two: The playable character is falling (because, you know, gravity)… we come to the frame where our character “lands on the ground,” great! But wait! Look out! An incoming projectile which you literally only have one frame to dodge! You’ve decided to use FixedUpdate, but you have a boolean flag so that you only process user input once per rendered frame. Once again, this is a bad idea. You WANT what I’ve seen others call “double input” because it isn’t on the frame that the character lands that gravity is applied, but rather the frame before! The first hit to FixedUpdate if (Button.Jump && IsGrounded) Jump() will fail… then the physics will be applied, collisions will occur, and FixedUpdate might be called again (possibly several times!) and/or Update will be called. Technically, we should check if the character is both 1) grounded, and 2) attempting to jump in both FixedUpdate and Update… this way when THIS frame is rendered, the player will see that their character did in fact land on the ground, and is already beginning the “jump!” animation.
I threw together a simple MonoBehavior2 to show the order that Unity calls these events to reiterate the importance of using both FixedUpdate and Update for input/physics changes. See the comments for the difference between fired events at different frame rates.
I have a hoverboard simulator where the board and player rotate about the Z axis in response to mouse input, with the turn radius being determined by the resulting bank angle. The rotation is governed by a torque being applied in FixedUpdate. I was also reading the mouse input during FixedUpdate, but occasionally the physics would hiccup, and in addition to a hitch in the framerate, I’d get a sudden rotation of 45+ degrees that rendered it unplayable. Moving the mouse input code to Update fixed the problem (there’s still the occasional framerate hitch but the sudden rotation errors are gone.)