- Home /
Is Input detection ok to do in fixedupdate?
I've seen a few things where people say not to detect for input in fixed update because its less accurate etc. However I just ran some tests that say differntly. I ran a script with some big loops in them to get the FPS to around 2. I then tested input detection in both update and fixedupdate. I actually found that it was more responsive in fixed update, what I mean by this is that when in fixed update, it takes about 2 frames for it to register after you press a button. In update it takes about 3 frames after you press the button for it to register. So not only do keypresses always register in fixedupdate, they seem to be more responsive. Thoughts?
So based off everyone's replies, I ran some more tests. I detect for input and then store that input into a variable so I can use it across update and fixedupdate. I also make the variable = $$anonymous$$eyCode.None every loop. I then run this code in update and check the variable in fixedupdate... I tested at 2fps, ~30fps, ~60fps and I'm pressing the D key (key I'm detecting) as fast as I could possibly ever press a D key. Every press gets detected. I then switch the code parts around, so now i run the detection in fixedupdate and check the variable in update. Do the same test. Same results... I guess it just works, that's fine with me. Will still detect in update just because tho.
That is nice to know.
I must say my answer was entirely based on the documentation, I haven't ever tried to do anything different.
Yeah I've learnt to not entirely trust the docs and test yourself. For example I've never encountered a rigidbody falling to sleep. I've just tested rigidbody2D.Velocity = x in update and it worked fine at all those framerates. I haven't tried ones like AddForce etc. I have a feeling they will act differently. I shall test tomorrow!!
Rigidbodies certainly do fall asleep if the movement falls below the defined threshold. The docs are rarely wrong and you should normally trust them (but not quite always; there are occasional mistakes). Typically it's a misunderstanding of the docs rather than them actually being wrong.
Sorry I should have said this was in 4.3 that I couldn't get a rigidbody to sleep, I haven't actually tried in 4.5 as of yet. As for the docs, I just saw this:
"When applying movement calculations inside FixedUpdate, you do not need to multiply your values by Time.deltaTime. This is because FixedUpdate is called on a reliable timer, independent of the frame rate."
This is not true at all. It implies that fixedupdate automatically multiplies your values by delta time when infact it's the physics methods that do this. You can run all your physics code in update and not have to multiply by delta time either.
In case you do this in Update, you'll be affected by jittering. In case of FPS irregularities (occasional frame drops) it will be considerable. In FixedUpdate there is no such a problem. Therefore you don't need to use time.deltaTime there. But of course in case you don't use deltaTime in FixedUpdate, the result will be much faster so you need to count with that. But ins$$anonymous$$d of time.deltaTime you can slower it down by a constant or something. Object movement will be still fluent in FixedUpdate.
No but, FixedUpdate is called at a defined rate no matter what, Update is framerate dependant, so if you run your game at 800fps ( no vsync ) and you run code in update, you are going to get significant differences to running at 60fps. multiplying by deltatime prevents this because you are multiplying your values by the time it took to complete the frame. I often have prototypes what work fine at 60 or so fps without using Deltatime, however I never tried them at higher or lower fps.
Yeah I understand what delta time is and when to use it, but what I quoted is wrong still.
"FixedUpdate is often called more frequently than Update."
I guess this is sort of true considering most console games are 30fps, but a 2D game would be running at 60 most of the time so again this is not entirely true.
Answer by Kiwasi · Jul 08, 2014 at 02:50 AM
You should be shot for trying to run a game at 2 FPS, how can that be defined as fun? :)
As I understand it the reason for using Update is that input data is changed every frame. So if you run two FixedUpdate cycles during one frame then the same input data will be read twice. On the other hand if you run two frames during one FixedUpdate then some input data will be missed. (In some cases this does not matter, jumping is one where this really shows)
The typical flow goes like this
Get input in Update
Apply changes to physics in FixedUpdate
But seriously, use a coroutine or something. There is no way you should accept a frame rate of 2.
I ran a script with some big loops in them to get the FPS to around 2
I believe he forced it to test Input response in FixedUpdate under low framerate conditions.
Whoops, my bad. $$anonymous$$y general comments are still valid though. If you read input in Update you are guaranteed to get every input from the user once and only once. If you get input in FixedUpdate you may get each input more or less then once.
So if you run two FixedUpdate cycles during one frame then the same input data will be read twice.
That seems to be wrong, at least in Unity 5. After testing it, I could read the input (GetButton()) with the same precision I could achieve with WinAPI's Get$$anonymous$$eyState(), which suggests that the Input itself might be processed more frequently. See my answer for test's results.
GetButtonUp()/GetButtonDown() however are a different story, their states are changed every Update().
EDIT: I was partially wrong, the input time precision won't ever exceed the Update()'s frequency, but apparently it's still better to read the key states in FixedUpdate() if that makes sense in a particular situation.
Answer by s-m-k · Apr 16, 2015 at 05:36 PM
I've experienced similar issue with responsiveness. I'm doing a very fast-paced game, so that matters a lot in my case.
I tested WinAPI's GetKeyState() against saving input state in Update() and checking it in FixedUpdate() and got similar results to OP's - the Update()'s saved data was delayed if Update()'s frequency was similar to/lower than FixedUpdate()'s. That resulted in noticeable lag even at 60fps + v-sync. In that case, using Input in FixedUpdate() gave me better time resolution, which matters a lot in fast-paced games.
I say it's perfectly valid to check the input in the FixedUpdate() if you need better accuracy/responsiveness but you're OK that you might miss some input data (like user pressing and quickly releasing a button between frames). It works well for platform-like movement even if "Every second v-blank" option is enabled.
However, we should remember that Up()/Down() thingies will still require Update() to function properly. Again, you can roll your own up/down mechanism based on current button's state if you need similar responsiveness and if you're OK that you can miss too-quickly-pressed buttons.
Also I found out that putting all logic in Update() and limiting the framerate with Application.targetFrameRate gave me even better feel than fiddling with FixedUpdate() (it's probably because Update() depends on render speed, FixedUpdate() doesn't, so the rendered image might still be one frame late if the desync happens), so maybe that would be better in your case.
So, we shouldn't get too religious about those things in case of GetButton(), GetAxis() etc. It just depends on the case.
The code I used in the test (it's a body of MonoBehaviour class used, I just removed the unrelated stuff). Note that I tested it with "Every second v-blank" quality setting:
[DllImport("user32.dll", SetLastError = true)]
static extern Int16 GetKeyState(UInt16 virtualKeyCode);
bool test = false;
void Awake() {
}
void Update() {
test = GameInput.GetAxisRaw("Horizontal") < 0;
Debug.Log("UPDATE");
}
void FixedUpdate() {
const ushort VK_A = 0x41;
Debug.Log(GetKeyState(VK_A) + " " + test + " " + (Input.GetAxisRaw("Horizontal") < 0));
Debug.Log("FIXED_UPDATE");
}
The result:
The actual movement's feel of responsiveness conforms the test results.
Please try it yourself and share results.
Just saw your answer. A lot people get confused about where they should do what. Of course "state information" can be queried wherever you like since it doesn't represent an event. The main problem are events (like key down / up).
Also what seems to confuse people is that the docs recommend "use AddForce (only) in FixedUpdate". This is actually nonsense. They mean continously applied forces should be applied in FixedUpdate. One-time-forces / impulses should be applied in Update. So jumping would be done in Update, not in FixedUpdate.
Next thing is you should try to $$anonymous$$imize the interaction between Update and FixedUpdate. So don't "prepare" something in Update which is being used in FixedUpdate.
FixedUpdate can be appear slightly more responsive than Update but not necessarily. You just have to consider the order in which things happen. Unity's main loop looks roughly like this:
main()
{
while(true)
{
updateInput();
while(physicsTime < gameTime)
{
FixedUpdate();
InternalPhysics();
physicsTime += Time.fixedDeltaTime;
}
Update();
Render();
gameTime += Time.deltaTime;
}
}
As you can see FixedUpdate always runs before Update (if it actually runs at all). However since you won't see anything before the next Render() both will receive the input at the same "visual" time.
As said previously if you want to move your character by applying continous forces or by using Rigidbody.$$anonymous$$ove, read the state input in FixedUpdate. Event based stuff (jumping, shooting) should always be handled in Update.
The best visual result in sense of smooth movement and fastest responsiveness you get when you do everything in Update. However when you want / need collisions and have the movement time based (not frame based) you have to put your movement into FixedUpdate.
Using FixedUpdate will always produce jitter. Depending on your relative speed you might not notice it but it's there. It can never be visually smooth since FixedUpdate has a different frequency than Update.
$$anonymous$$eep in $$anonymous$$d that input (state information and events) is only updated once per frame and doesn't change during the frame. Update is called exactly once per frame and is perfectly in sync with the visual update. So input state information can be read anywhere inside a frame, it doesn't matter where. Input event information however should only be processed in Update since this information only lasts one frame. Since FixedUpdate might run several times during one frame (VisualFPS < PhysicsFPS) or not at all (VisualFPS > PhysicsFPS) events processed in FixedUpdate lead to unpredictable results.
Yeah, that sums everything up, thanks for clarification, I just needed to test that up before I (almost) understood how it works and thought that I might help others with my (rough) results.
Answer by Cheetoturkey · Jul 08, 2014 at 02:54 AM
Well FixedUpdate() is for physics but if the game was running at lets say 100fps there would be two calls to Update for every call to FixedUpdate However if its running at say 30 frames per second it would mean that sometimes there would be more FixedUpdate calls then Update Input detection would be okay to do but its not recomeneded because in FixedUpdate the input could possibly be missed.
I just ran another test.
if (Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.Space))
{
spaceClicked = true;
}
else
{
spaceClicked = false;
}
Put this in update then in fixed update I put
if (spaceClicked)
{
Debug.Log ("SPACE CLIC$$anonymous$$ED");
}
The results were SPACED CLIC$$anonymous$$ED was not debuuged every time i hit the space bar, I got the exact same results switching the two pieces of code around
Answer by Eric5h5 · Jul 08, 2014 at 04:57 AM
You can't use FixedUpdate to do input detection such as keypresses. FixedUpdate does not necessarily fire every frame, so input will be lost sometimes. You can potentially do axis input, though, since holding down a key will return a value continuously over many frames. The *Up and *Down events are true only for a single frame though.
Answer by jonjons · Aug 06, 2017 at 11:22 AM
It just doesnt work using Up = Input.GetButtonDown("verticalUP"); in update() gives less delay than using it in fixedpdate()
but it just gets weird it doesnt always fire when the player moves foward and whatever.
Your answer
Follow this Question
Related Questions
How do I pass an input in Update() to FixedUpdate() for Physics movement? 2 Answers
Jumping randomly doesn't work 2 Answers
Why Do Inputs Have to Been in Update (Rather than FixedUpdate)? 3 Answers
Input and applying physics, Update or FixedUpdate? 3 Answers
Not registering input when checking input in Update and using input in FixedUpdate 1 Answer