Hey, beginner coder here, I’ve got a question that seemed to be asked fairly often but I looked around for like 30 minutes and didn’t find an answer, so I’ve got my player and everything works fine aside from the IsGrounded variable, I put it so it outputs onto the console and it always outputs as false, this makes it impossible for me to add gravity correctly or to add a jump mechanic, the most I managed to narrow it down to is IsGrounded just not detecting the ground, because it does stay directly under the player at all times, here’s the code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 12f;
public float gravity = -9.81f;
public float jumpHeight = 3f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
Vector3 velocity;
bool isGrounded;
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if(isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
Debug.Log(isGrounded);
}
}
I tried the calling the controller.isGrounded script before, it didn’t work, now I realize that I have a void Start(), thank you so much! It seems to be working fine now, really appreciate the help, definitely answered the questtion.
That won’t have affected anything. Monobehaviours can have any number Unity messages, including none.
The way CharacterController.isGrounded works is that it checks if the capsule was intersecting with a collider the last time .Move() was called. To ensure this works reliably, you need a constant downward force pushing the the controller against the ground.
Ok, then I must’ve screwed up somewhere else, isGrounded seems to work now, however another issue has come up, jump only works when I press forward, even if isGrounded = true, any issue as of why this could be happening, cause I’ve got zero clue, here’s the code.
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 12f;
public float gravity = -9.81f;
public float jumpHeight = 3f;
public Transform groundCheck;
public float groundDistance = 5f;
public LayerMask groundMask;
Vector3 velocity;
bool isGrounded;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if(controller.isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
if(Input.GetButton("Jump") && controller.isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2 * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
Debug.Log(controller.isGrounded);
}
}
Taking a look, you’re calling Controller.Move() twice in the same update loop. You should only be making one call to .Move() per loop as this is likely the cause of the unwanted behaviour. Additionally…
CharacterController is a fancy form of rigid body, meaning it’s evaluated in the same interval as FixedUpdate. When wanting to manipulate rigid bodies with inputs, you poll movements in Update and apply the values in FixedUpdate.
In your case you can build a value for velocity in Update, and use that value in FixedUpdate in a single .Move() call. I would provide code examples though I’m not in front of an IDE and won’t be for the next three days.
Alright, I understand how calling more than one .Move() can definitely screw it up, but if I get rid of either one it either gets completely rid of gravity, or it gets rid of movement, I’ll try to see what I can do to remove one, it most likely seemed like the issue.
I’ve never used FixedUpdate() before, I’ll have to look up how to use that, I do appreciate all the help you’ve been giving me, and while the code is still broken I understand more than I did before about a possible solution.
Yo! That’s insane! I’ll definitely have to check that out, right now I’ve moved onto another project, but I’ll definitely revisit this when I have time, I really appreciate the help!
I’ve been running into the very same issue and they way I solved it for me was by locking the playerVelocity.y to a value o -1.0f when your grounded, before I used a value of -0.25f but this wasn’t enough and simply pushing it to negative -1 solved it for now atleast. Hope it helps