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

Resolved GetKeyDown detection in Update and FixedUpdate.

Discussion in 'Scripting' started by CFK, Oct 6, 2023 at 7:48 PM.

  1. CFK

    CFK

    Joined:
    Dec 13, 2014
    Posts:
    12
    if I detect a GetKeyDown in FixedUpdate, it will miss the input if the frame only runs Update.

    Conversely, if I detect GetKeyDown in Update, could it be missed if the frame only runs FixedUpdate?
     
  2. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    19,971
    FixedUpdate() is a fraud. It doesn't run independent of the frame rate. Instead it runs as many times as needed each frame in order to catch up to its target speed. That means it could run multiple times or it could run zero times. If you store the value of GetKeyDown() in Update() it will be available to FixedUpdate().

    GetKeyDown() and GetKeyUp() don't work in FixedUpdate() because the code that handles their current state isn't being executed with each FixedUpdate() but with Update(). So if you try to use them in FixedUpdate() you will see incorrect state info.

    https://forum.unity.com/threads/the-truth-about-fixedupdate.231637/
     
    Last edited: Oct 6, 2023 at 8:06 PM
  3. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,264
    There is no such thing, as far as I know. Update runs every frame.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,283
  5. CFK

    CFK

    Joined:
    Dec 13, 2014
    Posts:
    12
    thank you for all the helps.

    after some research and some testing using the following script.

    i believe that
    1. the GetKeyDown always pickup by Update with no miss.
    2. the GetKeyDown always detect at the Update.
    3. If GetKeyDown called in FixedUpdate it will use the key-state at the last Update.

    If the FixedUpdate run 10 times faster than Update, if key pressed at the last Update frame, all 10 FixedUpdate will consider the GetKeyDown is True. Even only press the key once.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class test_fixed_update_update_getKeyDown : MonoBehaviour
    4. {
    5.     int total_key_down = 0;
    6.     int keyDown_FixedUpdate = 0;
    7.     int keyDown_Update = 0;
    8.  
    9.  
    10.     void Awake()
    11.     {
    12.         // Time.fixedDeltaTime = 0.04f; //25fps
    13.      
    14.         // Application.targetFrameRate = -1;
    15.         // Application.targetFrameRate = 50;
    16.         // Application.targetFrameRate = 25;
    17.         Application.targetFrameRate = 5;
    18.     }
    19.     void FixedUpdate()
    20.     {
    21.         if (Input.GetKeyDown(KeyCode.H))
    22.         {
    23.             keyDown_FixedUpdate++;
    24.         }
    25.         print($"Fixed:{keyDown_FixedUpdate} Update:{keyDown_Update}");
    26.     }
    27.     void Update()
    28.     {
    29.         if (Input.GetKeyDown(KeyCode.H))
    30.         {
    31.             keyDown_Update++;
    32.         }
    33.     }
    34. }
    35.  
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,283
    Don't do it that way.

    - check GetKeyDown() in Update()
    - if true, set a boolean

    - check the boolean in FixedUpdate()
    - if true:
    --> take action
    --> clear the boolean

    This is just basic input event processing logic. You will see it everywhere.
     
  7. CFK

    CFK

    Joined:
    Dec 13, 2014
    Posts:
    12
    thank you Kurt-Dekker

    i got your idea.
     
  8. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    421
    Code (CSharp):
    1.    void FixedUpdate()
    2.    {
    3.       if (Input.GetKey("jump") && Grounded())
    4.          rb.velocity.y+=10;
    5.  
    6.       if (Input.GetKey("shoot") && Time.time>shootTime)
    7.       {
    8.          Instantiate(bullet,transform.position,transform.rotation);
    9.          shootTime=Time.time+1;
    10.       }
    11.  
    12.       if (Input.GetKey("poop") && poopAvailable)
    13.       {
    14.          Instantiate(poop,transform.position,transform.rotation);
    15.          poopAvailable=false;
    16.       }
    17.    }