My Character controller gravity is not working as intended.. Help please?

Hey all.

So I’m trying to program a simple character controller system for a character controller with the standard, move left, right, jump, double jump etc.
However the gravity that i have implemented with the help of a tutorial i found online seems to be a little buggy. Basically when the player steps off a platform, he drops at full speed, however, when he jumps gravity seems to be working normally.
I’m fairly new to coding so i appologise if this is a super easy fix, but would love a bit of help.

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

public class Player : MonoBehaviour
{
    [SerializeField]
    private float _moveSpeed = 15f;
    [SerializeField]
    private float _sprintSpeed = 22f;
    [SerializeField]
    private float _jumpspeed = 1.8f;
    [SerializeField]
    private float _gravity = 4f;
    [SerializeField]
    private float _sprintGravity = 2.72f;
    [SerializeField]
    private float _doubleJumpMultiplier = 0.8f;

    private CharacterController _controller;

    private float _directionY;

    private bool _canDoubleJump = false;
    private bool _isSprinting = false;
    private bool _isJumping = false;

    // Start is called before the first frame update
    void Start()
    {

        _controller = GetComponent<CharacterController>();
       
    }

    // Update is called once per frame
    void Update()
    {
        float horizontalInput = Input.GetAxis("Horizontal");
        float verticalInput = Input.GetAxis("Vertical");

        Vector3 direction = new Vector3(horizontalInput, 0, verticalInput);

        // Is the player currently in the air
        if (_controller.isGrounded)
        {
            _isJumping = false; // if grounded then no
        }
        else
        {
            _isJumping = true; // if in the air then yes
        }

        // Can the player jump / double jump
        if (_controller.isGrounded)
        {
            _canDoubleJump = true;

            // if the player presses the jump button, makes the player jump
            if (Input.GetButtonDown("Jump"))
            {
                _directionY = _jumpspeed;
            }


        }

        // if the player is not gorunded but presses the jump button, lets the player use the double jump
        else
        {

            if (Input.GetButtonDown("Jump") && _canDoubleJump)
            {
                _directionY = _jumpspeed * _doubleJumpMultiplier;
                _canDoubleJump = false;
            }
        }


        // Detects if the player is sprinting and adjusts move speed and gravity accordingly
        if (Input.GetKey(KeyCode.LeftShift) && _controller.isGrounded)
        {
            _moveSpeed = _sprintSpeed;
            _isSprinting = true;
            _gravity = _sprintGravity;
        }
        // Detects if the player is moving at sprint speed in the air
        else if (_isSprinting && _isJumping)
        {
            _moveSpeed = _sprintSpeed;
            _gravity = _sprintGravity;
        }
        // Reverts the player movement speed and gravity to normal
        else
        {
            _moveSpeed = 15f;
            _isSprinting = false;
            _gravity = 4f;
        }



        _directionY -= _gravity * Time.deltaTime;

        direction.y = _directionY;

        _controller.Move(direction * _moveSpeed * Time.deltaTime);
    }
}

It’s kinda hard to say written like that… there are multiple checks of the jump input, multiple queries of the various booleans, it’s a bit over-wrought if you will.

If you want to debug this, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run?
  • what are the values of the variables involved? Are they initialized?

Knowing this information will help you reason about the behavior you are seeing.

If you want to start from a cleaner example, there are many out there. Here’s one I made for the Unity controller, after their example code became broken earlier this year.

I wrote about this before: the Unity example code in the API no longer jumps reliably. I have reported it. Here is a work-around:

2 Likes