Search Unity

Getting input in Update() and execute movement in FixedUpdate()

Discussion in 'Scripting' started by sampa93, Sep 18, 2020.

  1. sampa93

    sampa93

    Joined:
    Jul 18, 2020
    Posts:
    10
    What happens if I get my input values in Update() and execute movement in FixedUpdate() depending on them? I heared I should do it this way - but imagine following scenario:

    Code (CSharp):
    1. void Update()
    2. {
    3.       jump = Input.GetButtonDown("Jump");
    4. }
    5.  
    6. void FixedUpdate()
    7. {
    8.        if(jump == true)
    9.        {
    10.              jump();
    11.        }
    12. }
    Frame 0: Player presses "jump" (Update)
    Frame 0: jump = true (Update)
    Frame 1: Player releases "jump" (Update)
    Frame 1: jump = false (Update)
    Frame 2: physic calculations start -> jump == false -> dont jump (FixedUpdate)
     
  2. adehm

    adehm

    Joined:
    May 3, 2017
    Posts:
    369
    You need to have another variable that stores that your player wishes to jump and upon fixed update using that it would then be reset.

    For instance:
    Code (CSharp):
    1.     void Update()
    2.     {
    3.           if(!jump && Input.GetButtonDown("Jump") jump = true;
    4.     }
    5.    
    6.     void FixedUpdate()
    7.     {
    8.            if(jump)
    9.            {
    10.                  jump = false;
    11.                  //apply jump
    12.            }
    13.     }
    14.  
     
    sampa93 and Kurt-Dekker like this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,740
    That is close to the correct approach. The only problems are:

    - instead of assigning jump from GetButtonDown() every frame, do this:

    Code (csharp):
    1. if (Input.GetButtonDown("Jump")) jump = true;
    There actually is a significant logical difference that I'll let you work out.

    - in FixedUpdate() you want to also set
    jump = false;
    after you perform the actual
    DoJump()
    method. Otherwise you may still get double /triple jumps.

    - as an aside, you are recycling the identifier
    jump
    but I know what you mean and that you are likely just typing casually in the forum.

    Meanwhile, here is some timing diagram help:

    https://docs.unity3d.com/Manual/ExecutionOrder.html

    Which shows you why you don't want to assign every frame.

    EDIT: @adehm nailed it right as I pressed submit! NICE!!
     
    sampa93 likes this.
  4. sampa93

    sampa93

    Joined:
    Jul 18, 2020
    Posts:
    10
    @Kurt-Dekker

    Thanks. But how to react to the moveinput in update?

    When i get the values in update() by

    moveX = Input.GetAxis("Horizontal");
    moveZ = Input.GetAxis("Vertical");

    Is it still correct to do charactercontroller.move() with these parameters in FixedUpdate()? In this case i suggest there should be no set of "moved = true" or similar...?
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,740
    Gathering continuous input (such as what is returned from
    Input.GetAxis()
    versus
    Input.GetKeyDown()
    ) is less of a problem. You actually CAN do that in FixedUpdate().

    HOWEVER, it is good practice to break apart all the phases of your game's main loop:

    - Gather ALL the input, put it into variables

    - Process the input out of those variables, as appropriate

    The thinking behind this is that if you decide tomorrow "hey I want to support XBox Kinect for input!" then you have only one place to do the input gathering, because you have created a clear demarcation between "gather, process". It would just become "gather 1, gather 2, process"
     
    sampa93 likes this.
  6. sampa93

    sampa93

    Joined:
    Jul 18, 2020
    Posts:
    10
    Ok so there should be an Input Handler with

    Code (CSharp):
    1. if (Input.GetButtonDown("Jump")) jump = true;
    in Update()

    and a movement class with

    Code (CSharp):
    1.  
    2. if (inputHandler.jump)
    3. {
    4. Jump();
    5. inputHandler.jump = false;
    6. }
    in FixedUpdate()

    ?
     
    Kurt-Dekker likes this.