unity – .isGrounded is not working reliably

New to Unity and C#, though, I got the code from the official doc page for Character Controller and thought that should work by default.

When pressing the Jump button here it doesn’t always work. When checking if the player is grounded the variable groundedPlayer not always provides true when idle/not moving. Instead the value is constantly changing between true and false.

Below is my current code which was modified a little:

public class PlayerController : MonoBehaviour
{
  private CharacterController controller;
  private Vector3 playerVelocity;
  private bool groundedPlayer;
  private float playerSpeed = 2.0f;
  private float jumpHeight = 1.0f;
  private float gravityValue = -9.81f;

  private void Start()
  {
    controller = gameObject.AddComponent<CharacterController>();
  }

  void Update()
  {
    groundedPlayer = controller.isGrounded;
    if (groundedPlayer && playerVelocity.y < 0)
    {
      playerVelocity.y = 0f;
    }

    Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
    controller.Move(move * Time.deltaTime * playerSpeed);

    if (move != Vector3.zero)
    {
      gameObject.transform.forward = move;
    }

    print(groundedPlayer); //this will constantly return both false and true while idle

    // jumping mechanic
    if (Input.GetButtonDown("Jump") && groundedPlayer)
    {
      playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
    }

    playerVelocity.y += gravityValue * Time.deltaTime;
    controller.Move(playerVelocity * Time.deltaTime);
  }

}

It’s just that I feel dumb since basic jumping is this difficult to implement for me. I feel like I’m missing something very obvious. I found 1 working solution for me which is implementing coyote time, but it looks like a workaround and might provide more glitches in future. I also could try working on creating my own character controller, though that’s a whole different field.

Anyone had this issue before? How did you fix it?

Unity – Why aren't there isGrounded and Move properties for the CharacterController?

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

(RequireComponent(typeof(CharacterController)))

public class SC_FPSController : MonoBehaviour
{
    public float walkingSpeed = 7.5f;
    public float runningSpeed = 11.5f;
    public float jumpSpeed = 8.0f;
    public float gravity = 20.0f;
    public Camera playerCamera;
    public float lookSpeed = 2.0f;
    public float lookXLimit = 45.0f;

    CharacterController characterController;
    Vector3 moveDirection = Vector3.zero;
    float rotationX = 0;

    (HideInInspector)
    public bool canMove = true;

    void Start()
    {
        characterController = GetComponent();

        // Lock cursor
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    void Update()
    {
        // We are grounded, so recalculate move direction based on axes
        Vector3 forward = transform.TransformDirection(Vector3.forward);
        Vector3 right = transform.TransformDirection(Vector3.right);
        // Press Left Shift to run
        bool isRunning = Input.GetKey(KeyCode.LeftShift);
        float curSpeedX = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Vertical") : 0;
        float curSpeedY = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Horizontal") : 0;
        float movementDirectionY = moveDirection.y;
        moveDirection = (forward * curSpeedX) + (right * curSpeedY);

        if (Input.GetButton("Jump") && canMove && characterController.isGrounded)
        {
            moveDirection.y = jumpSpeed;
        }
        else
        {
            moveDirection.y = movementDirectionY;
        }

        // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
        // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
        // as an acceleration (ms^-2)
        if (!characterController.isGrounded)
        {
            moveDirection.y -= gravity * Time.deltaTime;
        }

        // Move the controller
        characterController.Move(moveDirection * Time.deltaTime);

        // Player and Camera rotation
        if (canMove)
        {
            rotationX += -Input.GetAxis("Mouse Y") * lookSpeed;
            rotationX = Mathf.Clamp(rotationX, -lookXLimit, lookXLimit);
            playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
            transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0);
        }
    }
}

On both, I get the same error: & # 39; CharacterController & # 39; does not contain a definition for & # 39; isGrounded & # 39; and no extension method accessible & # 39; isGrounded & # 39; accepting a first argument of type & # 39; CharacterController & # 39; could not be found (you are missing a using directive or an assembly reference?)