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

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:
    36,762
    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:
    36,762
    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.