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);
}
}