Unity 2018 2D Character Jump Glitch

I have this character controller I made below, after following several tutorials. I’m not animating my character, I just need it to move. I’ve got the left and right movement down, but the jump is funky. Sometimes when I press space, and more often when I hold it down, the character will jump higher than normal (like 2x-3x higher). I believe I’ve narrowed down to what’s causing that to happen, but I don’t know how to solve it. In order to check if the character is grounded, I use Physics2D.OverlapCircle(...). If the character is grounded, then I call rb.AddForce(Vector2.Up * JumpForce, ForceMode2D.Impulse) (rb is a RigidBody2D). What I believe is happening is the force gets added to the character normally. But in the next frame the character hasn’t moved up enough to actually leave the collider of the ground so Physics.OverlapCircle(...) catches the ground’s collider and adds the upwards force again. This is happens almost always following an accidental double bounce, because when the collider lands, it doesn’t stop instantly. The character’s collider will actually go into the ground’s collider and then shortly spring back up to where it should be.

So what should I do? Put the condition into the fixed update with the physics?

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

public class CharacterMovement : MonoBehaviour {

  public float MaxLeftRightSpeed = 2f;
  public float JumpStrength = 200f;
  public Transform GroundCheck;
  public LayerMask GroundLayers;

  private float groundRadius = 0.01f;
  private Rigidbody2D rb;
  private bool grounded = false;

  private void Start()
      rb = GetComponent<Rigidbody2D>();

  private void Update()
      if(grounded && Input.GetAxisRaw("Jump") != 0)
          rb.AddForce(Vector2.up * JumpStrength);


  private void FixedUpdate()
      grounded = Physics2D.OverlapCircle(GroundCheck.position, groundRadius, GroundLayers);

      float move = Input.GetAxisRaw("Horizontal");
      rb.velocity = new Vector2(move * MaxLeftRightSpeed, rb.velocity.y);

  private void OnDrawGizmos()
      Gizmos.color = Color.red;
      Gizmos.DrawWireSphere(GroundCheck.position, groundRadius);


I have had the same problem as you. But since the ability of my character to jump was only there for debugging purposes, I didn’t try to solve it. But anyway I will share my toughts with you.

In the first place, there is a better way of doing this because physics raycasts and overlaps are a somewhat expensive operation and should be used with care in my opinion. Use the Unity collision callbacks to detect when your player touches ground and when it leaves.

Something like this (untested):

private void OnCollisionEnter2D(Collision2D collision) {
        if (collision.name == "Ground") // your ground gameobject must be obviously called Ground
              grounded = true;

private void OnCollisionExit2D(Collision2D collision) {
       if (collision.name == "Ground")
                grounded = false;

But I think your problem will persist. You can try to implement a (very brief) cooldown on your jump wich will surely solve it :slight_smile: