Why the isGrounded value remains false?
I have did the following things:
-set the plane (ground) to Ground tag.
-set the groundLayer variable to Ground.
Here’s the code
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(CharacterController))]
public class PlayerController : MonoBehaviour
{
[SerializeField] CharacterController playerController;
public LayerMask groundLayer;
[SerializeField] InputActionReference move;
[SerializeField] InputActionReference jump;
public RaycastHit groundCheckHit;
public float speed;
public float verticalVelocity;
public Vector3 bottomPoint;
public float jumpHeight;
public bool isGrounded;
void Update()
{
Vector2 horizontalInput = move.action.ReadValue<Vector2>();
Vector3 camRight = Camera.main.transform.right;
camRight.y = 0f;
Vector3 camForward = Camera.main.transform.forward;
camForward.y = 0f;
Vector3 moveDirection = (camRight * horizontalInput.x + camForward * horizontalInput.y).normalized * speed;
if (isGrounded && jump.action.triggered)
{
verticalVelocity += Mathf.Sqrt(jumpHeight * 2f * Physics.gravity.y);
}
playerController.Move((moveDirection + Vector3.up * verticalVelocity) * Time.deltaTime);
}
void FixedUpdate()
{
bottomPoint = new Vector3(playerController.bounds.center.x, playerController.bounds.min.y + 0.05f, playerController.bounds.center.z);
isGrounded = Physics.SphereCast(bottomPoint, playerController.radius, Vector3.down, out groundCheckHit, 0.15f, groundLayer);
Debug.Log(groundCheckHit.distance);
Debug.DrawRay(bottomPoint, Vector3.down * 0.15f, isGrounded ? Color.green : Color.red);
}
}
Sounds like you wrote a bug… and that means… time to start debugging!
First place to check is if the spherecast is even changing the variable. If it isn’t, fix that.
If it is changing, find out why other things are not working: print it out in Update where you’re using it, and print out the value of that jump field.
Always best to copy all input to temp variables and act only on those variables because it makes debugging much simpler and less ambiguous.
By debugging you can find out exactly what your program is doing so you can fix it.
Use the above techniques to get the information you need in order to reason about what the problem is.
You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.
Once you understand what the problem is, you may begin to reason about a solution to the problem.
Remember with Unity the code is only a tiny fraction of the problem space. Everything asset- and scene- wise must also be set up correctly to match the associated code and its assumptions.
Unity’s CharacterController has always been more than a little goofy when it comes to many things, and this one is no exception.
It will only return true if the last Move() actually caused it to touch the ground BUT the character controller will automatically depenetrate each frame such that unless some forced is applied downward every frame then it will only be grounded for a single frame.
Basically, Move() applies no gravity itself and because of that the CharacterController will only ever report being grounded exactly one frame unless you manually apply your own force for gravity - which is usually what you want to do anyway.
Generally, I really just can’t recomend Unity’s CharacterController these days. It’s quirky, limited, and very slow. You’re better off looking at something like ‘Kinematic Character Controller’ on the asset store. It’s free and it was designed well enough that it landed it’s creator a job at Unity, which should speak of it’s quality. It is quite a bit more complex to use but absolutely worth it.
https://assetstore.unity.com/packages/tools/physics/kinematic-character-controller-99131