I’m new to Unity here. My script allows my player to walk, sprint, crouch, and jump. At present, it has a very strange problem:
When my character moves forward, left, and right, characterController.isGrounded is True, but when it moves backward, characterController.isGrounded becomes False. This prevents my character from jumping while moving backwards.
This problem is bugging me and I can’t find similar problems and solutions. I guess there may be a mechanism problem with characterController, or the order of some statements in my code is incorrect?
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
private Animator animator;
public Transform mainCamera;
private CharacterController characterController;
[Header("Move")]
public float crouchSpeed = 1f;
public float walkSpeed = 2f;
public float sprintSpeed = 5f;
public float rotationSpeed =5f;
public float moveSpeed;
private Vector3 moveDirection;
private bool isCrouch = false;
[Header("Jump")]
public float jumpHeight = 2f;
public float gravity = -10.0f;
private Vector3 playerVelocity;
private bool onGround;
private void Start()
{
characterController = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
moveSpeed = 0;
}
private void Update(){
// Move
moveDirection = mainCamera.right * Input.GetAxisRaw("Horizontal") + mainCamera.forward * Input.GetAxisRaw("Vertical");
if(moveDirection == Vector3.zero){
moveSpeed = 0;
animator.SetFloat("moveSpeed",moveSpeed);
}else if(isCrouch == true){
moveSpeed = crouchSpeed;
animator.SetFloat("moveSpeed",moveSpeed);
}else if(Input.GetKey(KeyCode.LeftShift)){
moveSpeed = sprintSpeed;
animator.SetFloat("moveSpeed",moveSpeed);
//animator.SetBool("isCrouch",false);
}else{
moveSpeed = walkSpeed;
animator.SetFloat("moveSpeed",moveSpeed);
}
// Rotate
if(moveDirection != Vector3.zero){
Vector3 lookDirection = moveDirection;
lookDirection.y = 0;
var targetRotation = Quaternion.LookRotation(lookDirection);
transform.rotation = Quaternion.Slerp(transform.rotation,targetRotation,rotationSpeed * Time.deltaTime);
}
// Jump
onGround = characterController.isGrounded;
Debug.Log(onGround);
if (Input.GetButtonDown("Jump") && onGround){
if(isCrouch == true){
isCrouch = !isCrouch;
moveSpeed = walkSpeed;
animator.SetBool("isCrouch",isCrouch);
}else{
playerVelocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
animator.SetBool("isJump", true);
Debug.Log("Jump");
}
}
if (onGround && playerVelocity.y <= 0){
playerVelocity.y = 0f;
animator.SetBool("isJump", false);
}
playerVelocity.y += gravity * Time.deltaTime;
characterController.Move(playerVelocity * Time.deltaTime + moveDirection * Time.deltaTime * moveSpeed);
}
// Crouch
public void OnCrouch(InputValue inputValue){
if (onGround){
isCrouch = !isCrouch;
if(isCrouch == true){
moveSpeed = crouchSpeed;
animator.SetBool("isCrouch",isCrouch);
}
else{
moveSpeed = walkSpeed;
animator.SetBool("isCrouch",isCrouch);
}
}
}
}