Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question characterController.isGrounded is false when I move backward?

Discussion in 'Scripting' started by Violet_64, Apr 13, 2024.

  1. Violet_64

    Violet_64

    Joined:
    Apr 3, 2024
    Posts:
    3
    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?

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.InputSystem;
    3.  
    4. public class PlayerController : MonoBehaviour
    5. {
    6.     private Animator animator;
    7.     public Transform mainCamera;
    8.     private CharacterController characterController;
    9.  
    10.     [Header("Move")]
    11.         public float crouchSpeed = 1f;
    12.         public float walkSpeed = 2f;
    13.         public float sprintSpeed = 5f;
    14.         public float rotationSpeed =5f;
    15.         public float moveSpeed;
    16.         private Vector3 moveDirection;
    17.         private bool isCrouch = false;
    18.     [Header("Jump")]
    19.         public float jumpHeight = 2f;
    20.         public float gravity = -10.0f;
    21.         private Vector3 playerVelocity;
    22.         private bool onGround;
    23.  
    24.     private void Start()
    25.     {
    26.         characterController = GetComponent<CharacterController>();
    27.         animator = GetComponent<Animator>();
    28.         moveSpeed = 0;
    29.     }
    30.  
    31.     private void Update(){
    32.         // Move
    33.         moveDirection = mainCamera.right * Input.GetAxisRaw("Horizontal") + mainCamera.forward * Input.GetAxisRaw("Vertical");
    34.         if(moveDirection == Vector3.zero){
    35.             moveSpeed = 0;
    36.             animator.SetFloat("moveSpeed",moveSpeed);
    37.         }else if(isCrouch == true){
    38.             moveSpeed = crouchSpeed;
    39.             animator.SetFloat("moveSpeed",moveSpeed);
    40.         }else if(Input.GetKey(KeyCode.LeftShift)){
    41.             moveSpeed = sprintSpeed;
    42.             animator.SetFloat("moveSpeed",moveSpeed);
    43.             //animator.SetBool("isCrouch",false);
    44.         }else{
    45.             moveSpeed = walkSpeed;
    46.             animator.SetFloat("moveSpeed",moveSpeed);
    47.         }
    48.        
    49.         // Rotate
    50.         if(moveDirection != Vector3.zero){
    51.             Vector3 lookDirection = moveDirection;
    52.             lookDirection.y = 0;
    53.             var targetRotation = Quaternion.LookRotation(lookDirection);
    54.             transform.rotation = Quaternion.Slerp(transform.rotation,targetRotation,rotationSpeed * Time.deltaTime);
    55.         }
    56.          // Jump
    57.         onGround = characterController.isGrounded;
    58.         Debug.Log(onGround);
    59.         if (Input.GetButtonDown("Jump") && onGround){
    60.             if(isCrouch == true){
    61.                 isCrouch = !isCrouch;
    62.                 moveSpeed = walkSpeed;
    63.                 animator.SetBool("isCrouch",isCrouch);
    64.             }else{
    65.                 playerVelocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
    66.                 animator.SetBool("isJump", true);
    67.                 Debug.Log("Jump");
    68.             }
    69.         }
    70.         if (onGround && playerVelocity.y <= 0){
    71.             playerVelocity.y = 0f;
    72.             animator.SetBool("isJump", false);
    73.         }
    74.         playerVelocity.y += gravity * Time.deltaTime;
    75.         characterController.Move(playerVelocity * Time.deltaTime + moveDirection * Time.deltaTime * moveSpeed);
    76.     }
    77.     // Crouch
    78.     public void OnCrouch(InputValue inputValue){
    79.         if (onGround){
    80.             isCrouch = !isCrouch;
    81.             if(isCrouch == true){
    82.                 moveSpeed = crouchSpeed;
    83.                 animator.SetBool("isCrouch",isCrouch);
    84.             }
    85.             else{
    86.             moveSpeed = walkSpeed;
    87.             animator.SetBool("isCrouch",isCrouch);
    88.         }
    89.         }
    90.        
    91.     }
    92. }
     
  2. Violet_64

    Violet_64

    Joined:
    Apr 3, 2024
    Posts:
    3
    By the way, I also discovered a problem with my code, LOL, that is, the height of my jump when walking is different from the height of my jump when sprinting, the latter is obviously lower. However, I only set one jump height, the same strange problem
     
  3. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    1,054
    You're pushing the character along its local forward axis which means that if you have a mouse look script and you're looking downwards towards the ground while pressing the back key then your character will lift off the ground slightly resulting in it no longer being able to jump. To prevent this you can flatten the moveDirection like so:
    Code (CSharp):
    1. // Move
    2. moveDirection = (mainCamera.right * Input.GetAxisRaw("Horizontal") + mainCamera.forward * Input.GetAxisRaw("Vertical")).normalized;
    3. moveDirection.y=0; // flatten the direction to prevent any upwards force which could cause us to lift off the ground slightly. Warning - character will now be slightly slower when looking up or down
    4. moveDirection=moveDirection.normalized; // normalize if you prefer a constant velocity regardless of looking up and down
    5.  

    Your rotation is a little unusual. Gamers typically want their character to strafe when using the A and D keys, but your character script also rotates. Although because of the way you've implemented the rotation code it will probably fail when pushing the back key. You can rotate with just this:
    Code (CSharp):
    1.         // Rotate
    2.         transform.Rotate(0,Input.GetAxisRaw("Horizontal") * 70 * Time.deltaTime,0);

    BTW - You're using both the old and new input systems which is a little unusual.
     
    Violet_64 likes this.
  4. Violet_64

    Violet_64

    Joined:
    Apr 3, 2024
    Posts:
    3
    Wow, your first code solved both of my problems at the same time. Now isGrounded has been corrected to true when walking backwards, and the height of the jump when sprinting is also the same as when walking! Awesome, thank you very much for your advice.
    Also, my plan for the rotation is that when aiming (right mouse button), the character will always face where the crosshair is aimed, and when not aiming (right now), the character will face the direction he is walking. If I had a car or a tank as my character, your second code would work perfectly!
    Also, I use both the old and new input systems LOL, and I didn’t even notice this problem myself. Thank you for bringing it up!