[SOLVED] Help with isGrounded check via SphereCast

Hi there! I am writing a grounded check using Unity, and it is always returning false for whether it is grounded.
Why is this?

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

public class Gravity : MonoBehaviour
{
   
    public bool isGrounded;
   
    [SerializeField]
    private float gravitySpeed;
    [SerializeField]
    private float gravityForce;
    [SerializeField]
    private float height = 2;
    [SerializeField]
    private float maxDist = 1;
    private Vector3 offsetHeight;
    private Vector3 spherePos;
    void Start()
    {
        CharacterController charCont = GetComponent<CharacterController>(); //Get the character controller component from the player object
        offsetHeight = new Vector3(0.0f, height/2, 0.0f);
       
    }
    // Update is called once per frame
    void Update()
    {
       
        checkIfGrounded();
    }
   
    private void checkIfGrounded()
    {
        RaycastHit hit; //get a hit variable to store the hit information
       
        spherePos = (transform.position - offsetHeight);
        if (Physics.SphereCast(spherePos, 1,  -transform.up, out hit, maxDist))
        {
            isGrounded = true;
        } else {
            isGrounded = false;   
        }
        Debug.Log(isGrounded);
   
       
       
    }
}

Thanks! - NPT

Does your ground have a collider?
You can also try drawing gizmos to see where your sphere is actually being cast incase some of your math is wrong.

I think perhaps you are casting to precisely where the bottom of the CharacterController’s shape is, judging by line 23 above.

This would mean the CC is keeping you from casting.

Try making doing 0.1 or 0.2 MORE distance than half of the height the way you are now.

EDIT: I’m no longer convinced the above is correct; but make some gizmos as RadRed suggests. :slight_smile:

Just so you know, the CC can be used for groundcheck.

I wrote about this before: the Unity example code in the API no longer jumps reliably.

I reported it to Unity via their docs feedback in October 2020. Apparently it is still broken:

Here is a work-around:

I recommend you also go to that same documentation page and ALSO report that the code is broken.

When you report it, you are welcome to link the above workaround. One day the docs might get fixed.

If you would prefer something more full-featured here is a super-basic starter prototype FPS based on Character Controller (BasicFPCC):

That one has run, walk, jump, slide, crouch… it’s crazy-nutty!!

Yep. The ground has a mesh collider. I tried using a gizmo and I couldn’t get it to work.

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

public class Gravity : MonoBehaviour
{
   
    public bool isGrounded;
   
    [SerializeField]
    private float gravitySpeed;
    [SerializeField]
    private float gravityForce;
    [SerializeField]
    private float height = 2;
    [SerializeField]
    private float maxDist = 1sf;
    private Vector3 offsetHeight;
    private Vector3 spherePos;
    void Start()
    {
        CharacterController charCont = GetComponent<CharacterController>(); //Get the character controller component from the player object
        offsetHeight = new Vector3(0.0f, .1f + height/2, 0.0f);
       
    }
    // Update is called once per frame
    void Update()
    {
       
        checkIfGrounded(); //
    }
   
    void checkIfGrounded()
    {
        RaycastHit hit; //get a hit variable to store the hit information
       
        spherePos = (transform.position - offsetHeight);
       
        if (Physics.SphereCast(spherePos, .5f,  Vector3.down, out hit, maxDist))
        {
            isGrounded = true;
        } else {
            isGrounded = false;   
        }
        Debug.Log(isGrounded);
   
       
       
    }
    void OnDrawGizmosSelected()
    {
        // Draw a yellow sphere at the transform's position
        Gizmos.color = Color.yellow;
        Gizmos.DrawSphere(spherePos, .5f);
    }
}

This is my code. The cast seems to be a meter or two below what it should, so when I raise it above the plane about a meter high it says it’s grounded, but above and below that it is false. How do I fix it?

From my experience, SphereCast will not return true in situation where the sphere already intersects the collider at the origin point. You might want to use OverlapSphere instead:

I rewrote the movement script and fixed the sphere cast. Thanks!