Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

CharacterController jumping not working

Discussion in 'Scripting' started by magnite, Jun 8, 2014.

  1. magnite

    magnite

    Joined:
    Dec 12, 2012
    Posts:
    125
    So this shouldn't be as big of an issue as it is. But when I switch between projects my scripts seem to break, or act differently.

    I wrote a script a while back as a motor for a character and I've been using it, or at least the same concept for moving a character controller but the jump seems to have 'broken.' I figured I may have been doing something wrong somewhere else in the code so I deleted everything except the bare minimum that it takes to walk around and jump, with no good results. The jump only goes to about 0.2 on the y axis no matter the jump height that I set, it's an instant snap rather than a smooth parabola like it should be and gravity takes FOREVER, although its the normal -9.81.

    Could anyone point out what's wrong?

    Code (CSharp):
    1. public class CharacterMotor : MonoBehaviour {
    2.     // Movement variables
    3.     public float forwardSpeed = 2.50f;
    4.     public float jumpHeight = 10.0f;
    5.  
    6.     // Internal variable
    7.     private CharacterController cc = null;
    8.     private Vector3 direction;
    9.  
    10.     // Use this for initialization
    11.     void Start() {
    12.         cc = GetComponent<CharacterController>();
    13.  
    14.         return;
    15.     }
    16.  
    17.     // Update is called once per frame
    18.     void Update() {
    19.         if (cc != null) {
    20.             direction = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
    21.             direction = transform.TransformDirection(direction);
    22.             direction *= forwardSpeed;
    23.      
    24.             if (cc.isGrounded && Input.GetButtonDown("Jump")) {
    25.                 direction.y = jumpHeight;
    26.             }
    27.          
    28.             direction.y -= -Physics.gravity.y * Time.deltaTime;
    29.          
    30.             cc.Move(direction * Time.deltaTime);
    31.         }
    32.      
    33.         return;
    34.     }
    35. }
     
    Last edited: Jun 8, 2014
  2. TVE

    TVE

    Joined:
    Oct 15, 2012
    Posts:
    379
    The Update function calls the data inside approximately 0.01 times per second. I believe the error is this line is constantly running:
    Code (CSharp):
    1. direction.y -= -Physics.gravity.y * Time.deltaTime;
    I see it is using deltaTime, but it is in the Update function. I believe this is the problem. Try writing it like this:

    Code (CSharp):
    1. public class CharacterMotor : MonoBehaviour {
    2.     void Start() {
    3.         cc = GetComponent<CharacterController>();
    4.         return;
    5.     }
    6.     // Update is called once per frame
    7.     void Update() {
    8.         if (cc != null) {
    9.             direction = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
    10.             direction = transform.TransformDirection(direction);
    11.             direction *= forwardSpeed;
    12.  
    13.             if (cc.isGrounded && Input.GetButtonDown("Jump")) {
    14.                 direction.y = jumpHeight;
    15.             }
    16.  
    17.              if (cc.isGrounded == false) {
    18.                 gravity();
    19.              }
    20.    
    21.    
    22.             cc.Move(direction * Time.deltaTime);
    23.         }
    24.  
    25. void gravity () {
    26. //Consider a yield statement to wait until character is up in the air
    27. while (cc.isGrounded == false) {
    28. direction.y -= -Physics.gravity.y * Time.deltaTime;
    29. }
    30. }
    31.  
    32.         return;
    33.     }
    34. }
    This is untested so let me know if there is errors or if it still does not work and I will put it into unity.
     
    Last edited: Jun 8, 2014
  3. magnite

    magnite

    Joined:
    Dec 12, 2012
    Posts:
    125
    There are problems with your code. Just from looking at it, the gravity will only be applied when the character is on the ground so there is no falling effect.
    Gravity needs to be applied every frame because it is a constant force, and correct me if I am wrong, it is modified by deltaTime so it's "realistic" with respect to the frame rate the game is being ran at.
     
  4. TVE

    TVE

    Joined:
    Oct 15, 2012
    Posts:
    379
    k look at my code, it checks to see if you are in air, then provides a constant loop of gravitational force until grounded again.
     
  5. magnite

    magnite

    Joined:
    Dec 12, 2012
    Posts:
    125
    Fixed.
    Code (CSharp):
    1. public class CharacterMotor : MonoBehaviour {
    2.     // Movement variables
    3.     public float forwardSpeed = 2.50f;
    4.     public float jumpHeight = 4.20f;
    5.    
    6.     // Internal variable
    7.     protected CharacterController cc = null;
    8.     protected Vector3 direction;
    9.     private Vector3 jumpDirection = Vector3.zero;
    10.  
    11.     // Use this for initialization
    12.     protected virtual void Start() {
    13.         cc = GetComponent<CharacterController>();
    14.    
    15.         return;
    16.     }
    17.    
    18.     // Update is called once per frame
    19.     protected virtual void Update() {
    20.         if (cc != null) {
    21.             direction = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
    22.             direction = transform.TransformDirection(direction);
    23.             direction *= forwardSpeed;
    24.            
    25.             cc.SimpleMove(direction);
    26.            
    27.             // Handle jump
    28.             if (cc.isGrounded && Input.GetButtonDown("Jump")) {
    29.                 jumpDirection.y = jumpHeight;
    30.             }
    31.            
    32.             // Apply gravity
    33.             jumpDirection += Physics.gravity * Time.deltaTime;
    34.             cc.Move(jumpDirection * Time.deltaTime);
    35.         }
    36.        
    37.         return;
    38.     }
    39. }