# How can I fix the player suspension in the air?

I'm making a 2D platformer with Unity. I used this video to write the code but with some little changes. I want to support both keyboard and gamepad, so I use the new Input System. I defined three variables called GroundedRememeber, JumpPressedRemember and JumpPressedRememberTime and basically they work like timers and check if the player leaves the ground and if so, then the player can jump when it is near the ground without the need to touch it. These timers weren't working, so I added a new method called TryJump and deleted some lines and now, the player is suspended in the air and moving upwards.

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

public class PlayerController : MonoBehaviour, PlayerInputActions.IPlayerActions
{
private PlayerInputActions controls;
private Rigidbody2D rb;
private Animator anim;
private bool facingRight = true;
private Vector2 moveInput;
[SerializeField] private float jumpForce;
float JumpPressedRemember = 0;

[SerializeField] float JumpPressedRememberTime = 0.2f;
float GroundedRemember = 0;

[SerializeField]  float GroundedRememberTime = 0.25f;
[SerializeField]  float HorizontalAcceleration = 1;
[SerializeField] [Range(0, 1)] float HorizontalDampingBasic = 0.5f;
[SerializeField] [Range(0, 1)] float HorizontalDampingWhenStopping = 0.5f;
[SerializeField] [Range(0, 1)] float HorizontalDampingWhenTurning = 0.5f;
[SerializeField] [Range(0, 1)] float JumpHeight = 0.5f;

private void Awake()
{
controls = new PlayerInputActions();

controls.Player.SetCallbacks(this);
}
void Start()
{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
void PlayerInputActions.IPlayerActions.OnMove(InputAction.CallbackContext context)
{
}

bool TryJump() {
if (GroundedRemember > 0) {
Jump();
return true;
} else {
JumpPressedRemember = JumpPressedRememberTime;
return false;
}
}
void PlayerInputActions.IPlayerActions.OnJump(InputAction.CallbackContext context)
{
switch (context.phase) {
case InputActionPhase.Performed:
TryJump();
break;
}
}
void Jump() {
GroundedRemember = 0;
JumpPressedRemember = 0;
}

void FixedUpdate()
{

if(facingRight == false && moveInput.x > 0){

Flip();

}else if (facingRight == true && moveInput.x < 0){

Flip();

}
}
void Flip(){

facingRight = !facingRight;
Vector3 Scaler = transform.localScale;
Scaler.x *= -1;
transform.localScale = Scaler;

}
void OnEnable()
{
controls.Enable();
}

void OnDisable()
{
controls.Disable();
}
void Update()
{

Vector2 GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
Vector2  GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);
bool Grounded = Physics2D.OverlapBox(GroundedBoxCheckPosition, transform.localScale, 0, groundLayers);

JumpPressedRemember -= Time.deltaTime;

GroundedRemember -= Time.deltaTime;

if (Grounded)  {
GroundedRemember = GroundedRememberTime;
}

if ((JumpPressedRemember > 0)) {
TryJump();

float HorizontalVelocity = rb.velocity.x;
HorizontalVelocity += moveInput.x;

if (Mathf.Abs(moveInput.x) < 0.01f)
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenStopping, Time.deltaTime * 10f);
else if (Mathf.Sign(moveInput.x) != Mathf.Sign(HorizontalVelocity))
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenTurning, Time.deltaTime * 10f);
else
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingBasic, Time.deltaTime * 10f);

rb.velocity = new Vector2(HorizontalVelocity, rb.velocity.y);
}
}
}

• Please fix the indentation of your code, it's nearly unreadable like this. Nov 13, 2020 at 2:21

Did you meant to execute this line every frame?

rb.velocity = new Vector2(rb.velocity.x, jumpForce);


If jumpForce is zero, this slows the player's fall by preventing gravity from accelerating them, since your zero-out their vertical velocity every frame. If jumpForce is greater than zero, it could cause the player to rise.

I don't see any useful function this line serves other than giving you problems to bring to StackExchange, so I'd say delete it.

• Thanks. I deleted it and now the player is on the ground and not suspended anymore. Do you see any line that prevents it from jumping and sticks it to the ground?
– Ali
Nov 13, 2020 at 6:31
• @Ali if (Grounded) { GroundedRemember = GroundedRememberTime; } What is "Grounded"? It's not defined in your script. Maybe it's always false. Nov 14, 2020 at 2:24
• @Kevin Yes, it was undefined. I deleted it but still can't jump. It seems like the jumping is somehow disabled with maybe a line of code.
– Ali
Nov 14, 2020 at 3:01
• It looks like you deleted the line that was referencing this variable, which was a mistake, because that ground check is very important to the mechanic you're implementing. Nov 14, 2020 at 5:47
• @DMGregory I'll ask another question about my current problem. That will be the last question that I ask about this code and anything related to that tutorial. Since I'm struggling with these problems for a long time, If I won't be able to find an answer to that question, I won't ask the same question again and I will use a regular groundCheck without timers instead. Thank you for helping me during this time.
– Ali
Nov 15, 2020 at 23:11