Jump Paused Until Player Stops Moving

Hello everyone! First time poster, so sorry if I screw something up!

I’ve been working on prototyping the mechanics for a 2D platformer in the Super Mario World style.

Just yesterday I finally got to the point where the player can both move and jump, even at the same time!

The issue is this: If the player releases one of the directional buttons (‘D’ for right), they are unable to jump for a few seconds afterward. But if they hold the direction button, or never pressed it to begin with, jumping works just fine!

I’m pretty sure the issue is Physics based, as using Debug.Log(‘Jump!’), I’ve seen that it fires every time the space bar is pressed, even if the sprite doesn’t actually jump.

My code is below:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    public float speed;
    public float sprintSpeed;
    private float currentSpeed;

    private Rigidbody2D rb;

    public float jumpAmount;
    public float jumpTime;
    public float jumpTimeCounter;

    public bool grounded;
    public LayerMask whatIsGround;
    public bool stoppedJumping;

    public Transform groundCheck;
    public float groundCheckRadius;

    public float gravityScale = 10;
    public float fallingGravityScale = 100;

    private PlayerInput playerInput;
    private PlayerInputActions playerInputActions;

    private void Start()
    {
        jumpTimeCounter = jumpTime;
    }

    private void Awake()
    {
        playerInput = GetComponent<PlayerInput>();

        playerInputActions = new PlayerInputActions();
        playerInputActions.Player.Enable();
        playerInputActions.Player.Jump.performed += PlayerJump;

        rb = GetComponent<Rigidbody2D>();

        currentSpeed = speed;
    }

    private void OnEnable()
    {
        playerInputActions.Player.Enable();
    }

    private void OnDisable()
    {
        playerInputActions.Player.Disable();
    }

    void Update()
    {
        grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);

        if (grounded)
        {
            jumpTimeCounter = jumpTime;
            rb.gravityScale = gravityScale;

        }

        if (!grounded && stoppedJumping)
        {
            rb.gravityScale = fallingGravityScale;
        }

        if (!grounded && !stoppedJumping && jumpTimeCounter > 0)
        {
            jumpTimeCounter -= Time.deltaTime;
        }
    }

    private void FixedUpdate()
    {
        Vector2 inputVector = playerInputActions.Player.Movement.ReadValue<Vector2>();
      
        if (inputVector.x != 0)
        {
            inputVector.y = 0;
            rb.AddForce(new Vector2(inputVector.x * currentSpeed, inputVector.y), ForceMode2D.Impulse);
        }

        if(inputVector.x == 0 && rb.velocity.x != 0)
        {
            rb.velocity = rb.velocity * 0;

            if(rb.velocity.x == 0)
            {
                return;
            }
          
        }
    }

    public void PlayerJump(InputAction.CallbackContext context)
    {
        if (context.started && grounded)
        {
            rb.AddForce(Vector2.up * jumpAmount, ForceMode2D.Impulse);
            stoppedJumping = false;
            Debug.Log("Jump!");
        }

        if (context.performed && !grounded)
        {
            if (jumpTimeCounter > 0)
            {
                jumpTimeCounter -= Time.deltaTime;
                rb.AddForce(Vector2.up * jumpAmount, ForceMode2D.Impulse);
            }

            if (jumpTimeCounter <= 0)
            {
                rb.gravityScale = fallingGravityScale;
                stoppedJumping = true;
            }
        }

        if (context.canceled)
        {
            jumpTimeCounter = 0;
            stoppedJumping = true;
        }
    }
}

I’m also using the new Input System. I’m not sure if I’m supposed to include screenshots of it or not, but how I have it set-up:

Movement is a Value/Vector 2, with the normal WASD controls, no interactions or processors.
Jumping is a regular Button press, set to Space Bar, and the binding itself as a “Press Only” interaction.

Any help would be greatly appreciated!

Edit:
I forgot to mention, that it’s something to do with this bit of code in FixedUpdate:

        if (inputVector.x != 0)
        {
            inputVector.y = 0;
            rb.AddForce(new Vector2(inputVector.x * currentSpeed, inputVector.y), ForceMode2D.Impulse);
        }
        if(inputVector.x == 0 && rb.velocity.x != 0)
        {
            rb.velocity = rb.velocity * 0;
            if(rb.velocity.x == 0)
            {
                return;
            }
          
        }

If I replace it with:

inputVector.y = 0;
rb.AddForce(new Vector2(inputVector.x * currentSpeed, inputVector.y), ForceMode2D.Impulse);

Then the jump works fine, and as intended. I have it in there, though, because without it the player slips and slides around, like with ice physics.

I can also say with almost-certainty that the issue isn’t inputVector.y = 0 because I’ve commented it out, and the issue persists.

I just wandered by and noticed you weren’t getting much help. Unfortunately I have never used the Physics2D system, don’t have Unity installed and have quite a poor memory… Hopefully I can still help a little.

In FixedUpdate you check for x input and if there is no input you set velocity to zero. If you set the rb velocity directly like this you will ignore the actions of forces acting on the rb this physics cycle, e.g. the jump forces you think you are adding.

You also keep doing this if rb.velocity.x != 0, but this is a conditional check against a float, which is often not a good idea as floats are often not quite 0, but instead just very small. In the 3D physics there are some hidden corrections that make small floats zero so you can get away with this, but I’m not sure if this holds for the 2D system. However, the velocity is probably almost never zero anyway due to the actions of the physics engine / gravity etc… Confirm what sequence things are happening in by adding a debug output here.

I’m not absolutely certain this is your problem, but if you are seeing that debug message and no jump is happening, either you are zeroing the rb velocity manually, applying an equal and opposite force somewhere else or you are not applying the force you think you are - I see jumpAmount is public, I assume because you were not aware of the [SerializeField] option or are you actually changing this value from outside of the class?

I suggest you add some extra debug lines so you can be sure that a non-zero jump force is applied and see when your code is setting velocity to zero.