Ground check issues

My ground check is always returning false. But once the detection distance is passed a certain value it always returns true no matter how far i am from the ground. Does anyone know the cause. Is it the scrips causing the issue? Or is it the settings on my rigged body or capsule collider? its hitting the plane. But the hit point stays at 0 0 0 even when i move and hit distance .05 even even i move. And says is grounded true no matter what until i lower the value to a certain point then it just says is grounded false.


using UnityEngine;
using UnityEngine.InputSystem;

public class VRPlayerMovement : MonoBehaviour
{
    [Header("References")]
    public Rigidbody playerRigidbody;
    public Transform headTransform;
    public Transform leftHandTransform;
    public Transform rightHandTransform;

    [Header("Input Actions")]
    public InputActionReference moveAction;
    public InputActionReference turnFlyBoostAction;

    [Header("Movement Settings")]
    public float walkSpeed = 3f;
    public float turnSpeed = 60f;
    public float maxFlySpeed = 5f;
    public float boostForce = 10f;
    public float glideSpeed = 8f;
    public float glideFallSpeed = 2f;
    public float glideArmDistance = 1.5f;
    public float boostDuration = 0.5f; // Duration of boost effect

    [Header("Input Thresholds")]
    public float flyThreshold = 0.1f;
    public float boostThreshold = -0.5f;
    public float turnDeadzone = 0.1f;
    public float moveInputThreshold = 0.1f;

    [Header("Stop Settings")]
    public float stopThreshold = 0.1f; // Threshold for considering movement input as zero

    [Header("Ground Check Settings")]
    public float groundCheckDistance = 0.1f;
    public LayerMask groundLayer;

    private Vector2 moveInput;
    private Vector2 turnFlyBoostInput;
    private bool isGrounded;
    private bool isGliding;
    private Vector3 boostVelocity;
    private float boostTimeRemaining;

    private void OnEnable()
    {
        moveAction.action.Enable();
        turnFlyBoostAction.action.Enable();
    }

    private void OnDisable()
    {
        moveAction.action.Disable();
        turnFlyBoostAction.action.Disable();
    }

    private void FixedUpdate()
    {
        moveInput = moveAction.action.ReadValue<Vector2>();
        turnFlyBoostInput = turnFlyBoostAction.action.ReadValue<Vector2>();

        CheckGrounded();
        UpdateGliding();

        Move();
        Turn();
        Fly();
        Boost();
        Glide();

        ApplyMovement();
    }

    private void CheckGrounded()
    {
        // Use a spherecast instead of a raycast for more reliable ground detection
        isGrounded = Physics.SphereCast(transform.position + Vector3.up * 0.1f, 0.05f, Vector3.down, out RaycastHit hit, groundCheckDistance, groundLayer);

        // Debug logging
        Debug.Log($"IsGrounded: {isGrounded}, Hit distance: {hit.distance}");

        // Visual debug
        Debug.DrawRay(transform.position + Vector3.up * 0.1f, Vector3.down * groundCheckDistance, isGrounded ? Color.green : Color.red);
    }

    private void UpdateGliding()
    {
        float armDistance = Vector3.Distance(leftHandTransform.position, rightHandTransform.position);
        bool wasGliding = isGliding;
        isGliding = !isGrounded && armDistance >= glideArmDistance;

        if (isGliding != wasGliding)
        {
            Debug.Log($"Gliding state changed. IsGliding: {isGliding}, IsGrounded: {isGrounded}, ArmDistance: {armDistance}");
        }
    }

    private Vector3 GetHorizontalMovementDirection()
    {
        Vector3 headForward = Vector3.ProjectOnPlane(headTransform.forward, Vector3.up).normalized;
        Vector3 headRight = Vector3.Cross(Vector3.up, headForward).normalized;
        return (headRight * moveInput.x + headForward * moveInput.y).normalized;
    }

    private void Move()
    {
        // Calculate movement direction and speed, but don't apply it yet
    }

    private void Turn()
    {
        if (Mathf.Abs(turnFlyBoostInput.x) > turnDeadzone)
        {
            float turnAmount = turnFlyBoostInput.x * turnSpeed * Time.fixedDeltaTime;
            Quaternion turnRotation = Quaternion.Euler(0f, turnAmount, 0f);
            playerRigidbody.MoveRotation(playerRigidbody.rotation * turnRotation);
        }
    }

    private void Fly()
    {
        if (turnFlyBoostInput.y > flyThreshold)
        {
            float flySpeed = Mathf.Lerp(0, maxFlySpeed, turnFlyBoostInput.y);
            Vector3 flyForce = Vector3.up * flySpeed;
            playerRigidbody.velocity = new Vector3(playerRigidbody.velocity.x, flyForce.y, playerRigidbody.velocity.z);
        }
    }

    private void Boost()
    {
        if (turnFlyBoostInput.y < boostThreshold && boostTimeRemaining <= 0)
        {
            Vector3 boostDirection;
            if (moveInput.magnitude > moveInputThreshold)
            {
                boostDirection = GetHorizontalMovementDirection();
            }
            else
            {
                boostDirection = headTransform.forward;
            }

            // Store the raw boost direction and magnitude separately
            boostVelocity = boostDirection.normalized * boostForce;
            boostTimeRemaining = boostDuration;
        }

        if (boostTimeRemaining > 0)
        {
            boostTimeRemaining -= Time.fixedDeltaTime;
        }
    }

    private void Glide()
    {
        if (isGliding && !isGrounded)
        {
            // Only apply glide fall speed if there is no upward fly input
            if (turnFlyBoostInput.y <= flyThreshold) // No upward input
            {
                Vector3 glideVelocity = playerRigidbody.velocity;
                glideVelocity.y = -glideFallSpeed; // Force downward velocity
                playerRigidbody.velocity = glideVelocity;
            }
            // If there is upward input, the Fly() method will control the vertical movement
        }
    }

    private void ApplyMovement()
    {
        // Calculate movement velocity based on input and current state
        Vector3 movement = GetHorizontalMovementDirection();
        float currentSpeed = (isGliding && !isGrounded) ? glideSpeed : walkSpeed;
        Vector3 movementVelocity = movement * currentSpeed;
        Debug.Log($"Movement applied. Speed: {currentSpeed}, IsGliding: {isGliding}, IsGrounded: {isGrounded}");

        // Get the current horizontal velocity
        Vector3 horizontalVelocity = new Vector3(playerRigidbody.velocity.x, 0f, playerRigidbody.velocity.z);

        // Determine if we should stop horizontal movement
        bool shouldStop = moveInput.magnitude < stopThreshold;

        // Handle boosting
        Vector3 boostHorizontalVelocity = new Vector3(boostVelocity.x, 0f, boostVelocity.z);
        float boostVerticalVelocity = boostVelocity.y;

        if (shouldStop)
        {
            // When not moving, use boost velocity (if any) or stop
            horizontalVelocity = boostHorizontalVelocity;
        }
        else
        {
            // Combine movement and boost velocities
            horizontalVelocity = movementVelocity + boostHorizontalVelocity;
        }

        // Calculate vertical velocity
        float verticalVelocity = playerRigidbody.velocity.y;

        // Apply gliding if necessary
        if (isGliding && !isGrounded && turnFlyBoostInput.y <= flyThreshold)
        {
            verticalVelocity = -glideFallSpeed;
        }

        // Combine horizontal velocity with vertical components
        Vector3 finalVelocity = new Vector3(
            horizontalVelocity.x,
            verticalVelocity + boostVerticalVelocity,
            horizontalVelocity.z
        );

        // Apply boost if active
        if (boostTimeRemaining > 0)
        {
            float boostMagnitude = boostVelocity.magnitude;
            Vector3 normalizedBoost = Vector3.ClampMagnitude(boostVelocity, boostMagnitude);

            finalVelocity += normalizedBoost;

            // Ensure the final velocity doesn't exceed the maximum allowed speed
            float maxSpeed = Mathf.Max(currentSpeed, boostMagnitude);
            finalVelocity = Vector3.ClampMagnitude(finalVelocity, maxSpeed);

            // Gradually reduce boost effect
            boostVelocity = Vector3.Lerp(Vector3.zero, boostVelocity, boostTimeRemaining / boostDuration);
        }
        else
        {
            boostVelocity = Vector3.zero;
        }

        // Apply the final velocity to the player
        playerRigidbody.velocity = finalVelocity;
    }
}


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

public class PhysicRig : MonoBehaviour
{
    public Transform playerHead;
    public CapsuleCollider bodyCollider;
    public ConfigurableJoint headJoint;

    public float bodyHeightMin = 0.5f;
    public float bodyHeightMax = 2f;

    // Update is called once per frame
    void FixedUpdate()
    {
        bodyCollider.height = Mathf.Clamp(playerHead.localPosition.y, bodyHeightMin, bodyHeightMax);
        bodyCollider.center = new Vector3(playerHead.localPosition.x, bodyCollider.height / 2, playerHead.localPosition.z);

        headJoint.targetPosition = playerHead.localPosition;
    }
}

On line 81 log what you’ve hit so then you can be certain the sphere cast actually hit the ground and not something attached to your player.

its hitting the plane. But the hit point stays at 0 0 0 even when i move and hit distance .05 even even i move. And says is grounded true no matter what until i lower the value to a certain point then it just says is grounded false.