Recently, I have been working on a character controller which’s movement was similar to the one’s in Celeste. I was able to get the run down, but the jump is really awkward. Despite all my efforts, the jump feels floaty and buggy, as the character jumps extremely high while moving. On the other hand, if I do a stationary jump, the character goes up every so slightly and comes back down. Along with that, the variable jump height is really weird. If I hold down the jump key for as long as possible, my character almost starts floating up, and when it hits the peak of the jump, it comes back down like a balloon (Even though I’ve added gravity to my code). Here’s the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[Header("Components")]
[SerializeField] private Rigidbody2D rb;
[Header("Layer Masks")]
[SerializeField] private LayerMask groundLayer;
[Header("Moevement Variables")]
[SerializeField] private float maxMoveSpeed;
[SerializeField] private float acceleration;
[SerializeField] private float deceleration;
private bool isChangingDirection => (rb.velocity.x > 0f && horizontalDirection < 0f) || (rb.velocity.x < 0f && horizontalDirection > 0f);
private float horizontalDirection;
[Header("Jump Variables")]
[SerializeField] private float jumpForce = 12f;
[SerializeField] private float airDecelerationRate = 2.5f;
[SerializeField] private float gravity = 8f;
[Header("Ground Check Variables")]
[SerializeField] private float groundRaycastLength;
private bool onGround;
private void Update()
{
horizontalDirection = getDirection().x;
if (Input.GetButtonDown("Jump") && onGround)
{
jump();
}
}
private void FixedUpdate()
{
checkCollision();
moveCharacter();
decelerateCharacter();
if (onGround)
{
decelerateCharacter();
}
else
{
airDecelerateCharacter();
jumpingGravityController();
}
}
private Vector2 getDirection()
{
return new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
}
private void moveCharacter()
{
rb.AddForce(new Vector2(horizontalDirection, 0f) * acceleration);
if (Mathf.Abs(rb.velocity.x) > maxMoveSpeed)
{
rb.velocity = new Vector2(Mathf.Sign(rb.velocity.x) * maxMoveSpeed, rb.velocity.y);
}
}
private void decelerateCharacter()
{
if (Mathf.Abs(horizontalDirection) < 0.1f || isChangingDirection)
{
rb.drag = deceleration;
}
else
{
rb.drag = 0f;
}
}
private void jump()
{
rb.velocity = Vector2.up * jumpForce;
}
private void checkCollision()
{
onGround = Physics2D.Raycast(transform.position, Vector2.down, groundRaycastLength, groundLayer);
}
private void OnDrawGizmos()
{
Gizmos.color = Color.black;
Gizmos.DrawLine(transform.position, transform.position + Vector3.down * groundRaycastLength);
}
private void airDecelerateCharacter()
{
rb.drag = airDecelerationRate;
}
private void jumpingGravityController()
{
if (rb.velocity.y < 0f)
{
rb.gravityScale = gravity;
}
else if (rb.velocity.y > 0f && !Input.GetButton("Jump"))
{
rb.gravityScale = gravity;
}
else
{
rb.gravityScale = 1f;
}
}
}
I’ve tried changing the gravity scale depending on different scenarios, getting rid of the gravity through code (The reason why I have gravity in the first place is because without adding in-code gravity my character falls way too slowly to the ground), but still the same results.
Kanav Gupta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.