Search Unity

Bug Alwais FixedUpdate() pressing a keyboard key trigger multiple times or not detected at all?

Discussion in 'Physics' started by AlanMattano, May 27, 2020.

  1. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    Dragon aborted.
    Meanwhile,
    I wish to use FixedUpdate to move physics game objects (using force).
    I love the idea of using my game also when the fps drops.
    But pressing a key, the function is triggered multiple times in Unity 2019.3 (using down or up)
    And the key pressed not detected at all in Unity 2020.1.b10

    CASE: (Case 1251039) http://fogbugz.unity3d.com/default.asp?1251039_brf10ilq936mco3n

    Is this a bug?

    Code (CSharp):
    1.  
    2. void FixedUpdate()
    3.     {
    4.         if (Input.GetKeyDown(myKey))
    5.         {
    6.             Debug.Log("[myKey] was press \n");
    7.             KeyWasPress();
    8.         }
    And when I press the keyboard key one time,
    Console
    "[myKey] was press"
    "[myKey] was press"

    1. What happened
    DESCRIPTION
    “#Beta2020Win_NVIDIA” Always using FixedUpdate() when a key is press inside the FixedUpdate() using Input.GetKeyUp or down, the key is not detected or detected multiple times.
    I try Down and up, Same problem. The keybord is working well.

    2. How we can reproduce it using the example you attached
    STEPS
    * Open the attached project
    * in it the script is included:
    Code (CSharp):
    1. public class BugExample : MonoBehaviour
    2. {
    3.     [Tooltip("[ESC]Is in charge of closing the actual window. If a window is open, this key will close it")]
    4.     public KeyCode exitMode = KeyCode.Escape;
    5.  
    6.     public int counter;
    7.  
    8.     void FixedUpdate()
    9.     {
    10.         if (Input.GetKeyDown(exitMode))
    11.         {
    12.             Debug.LogWarning("[ESC] \n Exit Window must be call!");
    13.             myPhisicsEvent();
    14.         }
    15.     }
    16.  
    17.  
    18.     void myPhisicsEvent()
    19.     {
    20.         Debug.LogWarning("myPhisicsEvent \n");
    21.  
    22.         counter++;
    23.     }
    24. }
    * Run the scen with the script attached to it
    * Press the [ESC] key in your keyboard

    ESPECTED: Since FixedUpdate is running several times per second, that each time [ESC] key is press (in a good normal way) the counter adds one more value. Also is expected one key detection for each good press if the physics update time stamp is altare.
    ACTUAL: The counter is not increasing each time the user press [ESC] or [KEY]assigned and in some casesone pressing one time the counter is trigger multiple times.


    Or I'm doing something wrong?

    Similar:
    https://forum.unity.com/threads/the-truth-about-fixedupdate.231637/
    https://forum.unity.com/threads/input-getkeydown-being-registered-multiple-times.456774/
     
  2. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    I assume the input system tracks the state of the key on a per-visual-frame-basis. FixedUpdate() can be called multiple times during a frame, so that's why you see it returning true multiple times, especially on low visual frame rates. I also assume that on high frame rates (100+ per second), there are situations where GetKeyDown doesn't return true at all because the event happens completely within two frames that fit into one physics frame.

    My advice is to set a property (like "escPressed = true") in your components Update() function and set it to false within your FixedUpdate() when the function reacted to the event.
     
  3. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    Ye, I agree with your conclusion.
    But is a bug! lucubration: probably won't fix by design.

    But it is not expected and not what I want. I want to move that particular object at the exact moment (few ms) I press the key. Not waiting for the frame. My input system depends on fixed. not on the oscillation of the framerate.

    For example Flight simulator if you get 15fps and you pull back there is a big delay and the plane finishes not making the flare rotation and crashing into the runway. I want to stay in control also if the frame rate drops down. So that the player feels the game also with a low frame rate!
     
    Last edited: May 28, 2020
  4. DragonCoder

    DragonCoder

    Joined:
    Jul 3, 2015
    Posts:
    1,698
    Having higher physics-updates (aka FixedUpdate calls) than visual frames is quite unusual.. and let's be honest, <30 frames is kinda unplayable anyways. You do not really have to cover that as a games developer. Instead you should allow reducing graphics quality. It is often easier to do that than if it were the other way around and you had to gracefully degrade physics, AI or general game code when that became the bottleneck.

    So in most games you have more frames than physics updates and therefore it makes sense to tie this check to the Update function. In fact in those cases it actually does allow for more accurate response to user input than if it were tied to the FixedUpdate.

    The documentation is quite clear, I'd say because it does state: "returns true during the FRAME the key was started to be pressed".
    That said, the docu also encourages to do anything physics related in the FixedUpdate function and quite often, keyboard inputs are supposed to trigger physics task (like apply force etc.).
    So yeah, I fell into this trap too once - but a closer look at the description of the GetKeyDown command cleared the issue quickly :)
     
    Last edited: May 30, 2020