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.