Search Unity

New Input System Package and framerate-independent, real-time input monitoring

Discussion in 'Input System' started by erickim555, Jun 9, 2020.

  1. erickim555

    erickim555

    Joined:
    May 25, 2020
    Posts:
    2
    Does the new Input System Package support framerate-independent, real-time input monitoring?

    By "real-time", I mean: when we receive an input, we know exactly when that event occurred, eg relative to some reference time like Time.realtimeSinceStartup or AudioSettings.dspTime.

    By "Framerate-independent", I mean: if the game's framerate dips (60fps -> 20fps), then our ability to accurately monitor inputs should not be impacted.

    Context: I'm building a rhythm game in Unity 2D, imagine a Guitar Hero / DDR clone if you like. I need to listen for keyboard/controller events, and if the Player hits the spacebar at the correct time (eg in beat with the song), award them some points.
    More broadly: this question applies for any game that requires precise handling of user inputs. For instance, I've heard that fighting games require precise polling of user inputs in a manner that is uncoupled from the game render pipeline: https://forum.unity.com/threads/realtime-input-in-unity.54154/

    My understanding: The old input system's update rate is tied to Update(), eg framerate-dependent. Example: if the game FPS is 30, eg Update() is called every 1 / 30 = 0.033 seconds, then this means that I can only detect Player inputs every 0.033 seconds. This is too large of an input detection delay: for a 120 beats-per-minute track, where each quarter note occurs every 0.5 seconds, if I want a 10% time tolerance (0.05 secs of slack), this gives the allowable time to be [0.495, 0.505]. The 0.05 secs of slack is dangerously close to the Update() rate of 0.033 secs: there may be occasions where the Player did tap the spacebar at the correct "real" time within the 0.05secs slack range, but due to "unlucky" Update() call rate, the game reports that the Player did NOT press the spacebar in time. In other words, the input polling granularity is 0.033secs, which is too high for precision usecases.
    Unfortunately, moving the spacebar-press detection code to FixedUpdate() as a workaround doesn't work, because the old input system's update rate is explicitly tied to how frequently Update() is called. Thus, the only way to achieve framerate-independent input monitoring is to use a plugin that directly accesses the platform hardware to poll for events, rather than utilizing Unity's input system. This has its complications, in that you'd need to write a separate hardware poller for each target platform (windows vs ios vs android, etc).

    Question: With the new Input System Package, can I use it to achieve real-time framerate-independent input monitoring? If so, are there any pointers/tips on how to do so? For instance, how would I be able to not only detect that the Player pressed spacebar, but get the exact spacebar-press event time (eg relative to realtimeSinceStartup)?

    This link makes me hopeful, but it's a bit old (~2 years), so I wonder if there's been any new developments since then: https://forum.unity.com/threads/new-input-system-and-framerate-independance.543666/

    I apologize if this has been asked before, but initial Google searching didn't yield a definitive answer. Thanks in advance!
     
  2. There is no such thing as "real time" in Unity AFAIK.

    answer.PNG
    - you can read Inputs in Update only, then obviously you will get frame-rate dependent inputs.
    - you can read Inputs in FixedUpdate, then you will get the input in sync with the physx system. By default it is 50FPS, it can be set to any rate in the Project Settings/Time/Fixed timestep, and independent from the framerate*
    - you could read by hand, in update, fixedupdate, lateupdate, whatever. Obviously this won't be realtime since Unity have a framerate-dependent structure with the exception of the FixedUpdate.

    * independent from the framerate means only if the CPU has plenty of strength. If your framerate dips because of the sheer amount of work you put on the CPU and it can't handle it, nothing will save you from slow down. In that case the FixedUpdate will suffer as well, since there is no metal under it which could keep the 50Hz (by default) pace.

    ps: (edit) and there is a way to read the time of the event, so you can process them accordingly, AFAIk reading the InputSystem from a separate thread isn't possible currently AFAIK, but maybe @Rene-Damm will correct me if I'm wrong.
     
    Last edited by a moderator: Jun 9, 2020
    Tethip, f4bo, BAIZOR and 1 other person like this.
  3. erickim555

    erickim555

    Joined:
    May 25, 2020
    Posts:
    2
    Thanks for the information! Much appreciated :)

    Getting access to the event time would be perfect, this would let me more accurately implement the input-beat-detection system.

    I'm guessing that this InputEvent.time member will be what I'm looking for:
    https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Events.html
     
  4. ToT711

    ToT711

    Joined:
    Oct 7, 2016
    Posts:
    3
    I'm trying to create an FPS Camera Controller with Input System. My intention is to create the most "accurate" mouse look possible, and by that I mean it will be used in a competitive shooter style game where pixel-accurate mouse look is required.

    Here's what I have so far:

    Code (CSharp):
    1.   void Update()
    2.   {
    3.       rotation.x -= controls.Player.Look.ReadValue<Vector2>().y * sensitivity * Time.deltaTime; // Vertical look.
    4.       rotation.y += controls.Player.Look.ReadValue<Vector2>().x * sensitivity * Time.deltaTime; // Horizontal look.
    5.       rotation.x = clamp(rotation.x, -88f, 88f);
    6.       transform.localEulerAngles = rotation;
    7.   }
    I'm using InputActions and
    Process Events in Dynamic Updates
    in the settings.

    I have a couple of questions:

    1. Should I multiply the rotation by Time.deltaTime? I read conflicting posts that say you don't need to do this because the mouse delta is already "framerate independent". On the other hand, the InputSystem sample "SimpleDemo" includes snippets that do multiply the rotation by Time.deltaTime.
    2. If not, would this be the same for Gamepads? Or do they require Time.deltaTime?

    Thanks!