Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug UI Toolkit & (New) Input System - no events sent on low fps

Discussion in 'UI Toolkit' started by Maverick, Sep 26, 2023.

  1. Maverick

    Maverick

    Joined:
    Dec 18, 2009
    Posts:
    224
    When using UI Toolkit and New Input System.

    UI will not get any events (or rarely) if:
    - Update Mode Process Events In Fixed Update
    - Target frame rate is set to a low value, let set it to 5-10 fps (for testing purposes)

    Although the input system is processed about 50 times per second, ui is not receiving any (or very few) events.

    Same situation is when using Process Events Manually update mode. The only mode that works at low fps is Process Events In Dynamic Update.

    My understanding is that the new input system is supposed to be framerate independent (and it probably is), however something is not working properly (IMHO) when using both systems together.

    Could you please elaborate, maybe we are using it all in a wrong way.

    Thanks

    (Using Unity 2023.1.11f1 and New Input System 1.7.0)
     
    Last edited: Sep 26, 2023
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    FixedUpdate isn't frame independant. It just catches up with Update using an accumulator. If you have such a low FPS, then you will have tons of FixedUpdate calls bunched up before each Update call.

    Put some Debug.Log calls into a FixedUpdate and Update block and you'll see how they're being called.

    I'm not sure why the Fixed Update input processing option even exists to be honest, as it's a bit of a trap. Fixed Update should be for physics and nothing else.
     
  3. Maverick

    Maverick

    Joined:
    Dec 18, 2009
    Posts:
    224
    According to the docs, it should be frame independent. But, regardless of how it works, I would expect to receive input events on the first executed update, even if it's only 5 fps, and there are none.

    BTW, 5 fps is for testing purposes, just to make the problem worse. We noticed that at 30 fps and Process Events In Fixed Update, list scrolling, for example, is jerky and does not receive all clicks and/or other events.

    (Thanks for the answer)
     
    Last edited: Oct 2, 2023
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Yeah the docs are wrong, or at least misleading (so I've reported the page as such). Everything in the core player-loop happens on a frame-by-frame basis. FixedUpdate just checks if enough time has passed between the last frame and will run as many physics simulations as needed to fill that difference. Hence why it should only be used for physics, as it lets rigid bodies 'catch up' to non-physics stuff.

    If your inputs are being polled in Fixed Update, they only last as long as that one call to fixed update. As the frame rate is so low, you'll have a number of Fixed Update calls bunched up, meaning your input is probably only valid for one of those calls.

    I guess this comes down to how the Event System operates. But, nonetheless, the usual advice of 'poll input in Update, not Fixed Update' is still true even of the new Input system.
     
  5. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hi. I think @spiney199 's diagnostic is right, but I still call it a bug that it doesn't work with Fixed Update Mode. What's the point of that mode if it breaks UI? Maybe I'd understand it for the manual mode, because it's the user saying that they'll take care of things, but this Fixed Update Mode's definition implies that it shoud just work. So I'd consider reporting a bug.

    This page in the manual has a nice diagram explaining how the different updates work, in case it helps. I do think there are valid reasons to do some things that aren't strictly physics in FixedUpdate, but it's useful to know how it actually works.
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    I wonder what the point of the mode is at all, to be honest. It's pretty much always never been correct to poll input in Fixed Update, so I would love to know the intent was behind having that option.
     
  7. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    If I understand the docs correctly, it processes inputs right before FixedUpdate. FixedUpdate runs before Update in Unity's event loop, so it could be used to reduce input lag in certain games. Otherwise, you'd have to cache the input in Update and wait for the beginning of the next frame, or maybe even more in some cases, for the next FixedUpdate.

    Maybe, depending on the implementation, if it respects subframe times for inputs, it could spread multiple inputs over multiple FixedUpdate. That could be useful to support things like combos even during short fps drops. I'm being very hypothetical here, though.

    Other than that, for some types of games, it can be very convinient. It's less state to store and handle, less chances to make mistakes, less stuff to think about when designing game logic.
     
    Last edited: Sep 30, 2023
  8. TomTheMan59

    TomTheMan59

    Joined:
    Mar 8, 2021
    Posts:
    298
  9. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
  10. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,900
    The thing is, there is no valid reason to use
    FixedUpdate
    to handle input in Input System. The Input System tied to Unity's update loop either way, the most you can achieve using
    FixedUpdate
    for input is to miss some input and lock yourself on pause.
     
  11. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Well, it makes sense that it doesn't update when
    timeScale
    is zero, doesn't it?
    FixedUpdate
    doesn't run when
    timeScale
    is zero either. To be honest, I hadn't thought about that potential problem, but this behavior does make sense to me. It's not too uncommon for games to avoid pausing using
    timeScale
    because of problems like this. On the other hand, UITK checking inputs during Update when the Input System is configured to use FixedUpdate does seem like a bug to me.

    About the Input System being tied to the Unity's update loop, I wonder what the QA people meant. I took a brief look at the source code, and it does seem to at least consider FixedUpdate as a special case for things like time slicing. FixedUpdate does happen as part of Unity's event loop; maybe that's what they were talking about?
     
  12. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,900
    IDK. Maybe "logical" shutting down the input when it is handled "in FixedUpdate", but it's still stupid. People chooses this because they want to manipulate things on physical way. Pausing the game when you're manipulating through the physics engine is almost impossible through anything but timeScale. In theory you could track every object, cache velocities and whatnot, set them to zero and on continue you do it the other way around. But this is still stupid and unnecessarily complicated. Simpler to just slide the timeScale to zero.
    Unity not providing exclusion for input during timeScale changes is incredibly stupid. Not to mention you have other ways (and you should do it other ways) to enable/disable input. Through InputActionMaps.
     
  13. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    I think one either handles physics as a special case, or everything else that becomes an issue with timeScale set to zero. Handling physics as a special case would entail setting the physics update mode to manual, updating physics manually during FixedUpdate, and not updating physics when the game is paused. Handling the rest as a special case would mean things like changing Input System Settings programmatically when the game is paused. It's still a hassle, but not as much as caching the state of every physics object.

    I don't think it's good for anyone involved to insult others like that. That said, I do think it'd be nice if they provided a way to handle these problems better. I think it should be done with more granular options. It'd be nice if one could override the InputSystem's update mode per Input Action, or at least per Input Map. They already handle some types of input as a special case when updating, like some VR controls, and, after a brief look at the code, it seems doable. That way, gameplay inputs could be handled on FixedUpdate if needed, while navigation inputs stay on plain Update.