Update, FixedUpdate, Key Listening and Rigid Body

The relationship between these four things is so odd that I don’t know how to fix it now that a problem has occurred.

This is a very simple framework for role control scripts

void Move()
{
    float moveMultiple = Input.GetAxis("Horizontal");
    if (moveMultiple != 0)
    {
        rig.velocity = new Vector2(moveMultiple * moveSpeed * Time.deltaTime, rig.velocity.y);
    }        
}
void Jump()
{
    if (Input.GetKeyDown(KeyCode.W))
    {
        rig.velocity = new Vector2(rig.velocity.x, jumpForce * Time.deltaTime);
    }
}
void FixedUpdate()
{
    Move();
     Jump();
}

The first problem arises here [key press event] is not listened in FixedUpdate. When I press the jump key, the character sometimes jump up and sometimes does not jump up.

To solve this problem I made some adjustments to my script

void FixedUpdate()
{
Move();
}
void Update()
{
Jump();
}

I put jump() into update, however my character can’t jump normally. When I press jump, the character only moves a few pixels.
The unity documentation says that object movement should be manipulated in fixedupdate. This pattern is very confusing to me, I have to listen to the button in update and control the jump in fixedupdate. Adding a variable to specifically pass the keystroke state would make the script very complicated, and since the two updates are not synchronized it could lead to lost keystrokes in between.

I would like to know if there is a way to solve this problem so that I can listen to the keystrokes in fixedupdate or set the speed in update,The relationship between these four things is so odd that I don’t know how to fix it now that a problem has occurred.

FixedUpdate runs practically ‘slower’ than regular Update so it’s harder to read pressed keys. In this case I would separate the Jump function as it is read from the Input once (by press) and keep the Move function in the FixedUpdate as it’s slightly dynamic value. Also I got rid off the deltaTime from the jump, the ‘jumpForce’ value would have been too high. I would do this

private void Update()
{
     Jump();
}
private void FixedUpdate()
 {
     Move();
 }

void Move()
 {
     float moveMultiple = Input.GetAxis("Horizontal");
     if (moveMultiple != 0)
     {
         rig.velocity = new Vector2(moveMultiple * moveSpeed * Time.deltaTime, rig.velocity.y);
     }        
 }
 void Jump()
 {
     if (Input.GetKeyDown(KeyCode.W))
     {
         rig.velocity = new Vector2(rig.velocity.x, jumpForce);
     }
 }

As a general pattern, you should be looking for inputs in update, as update happens on a per-frame basis. Fixed update happens on a fixed timestep (0.2 seconds by default), which is generally what any physics based calculations should happen on for a variety of reasons. Though this timestep is why inputs can be missed, as Fixed Update is called many times less than Update.

A way to handle this is to use variables to store current inputs in update, then in fixed update you act on/apply those variables. For example, you can use a float that store the value of a GetAxis in an update call. Then in the fixed update call, you can use that in your movement code (ie: by multiplying an add force by the value).

Additionally, some of your strange behaviour might be due to setting velocity values, which often causes strange results. If you’re working with physics, movement might be better handled with AddForce.