Search Unity

Help needed with player jumping.

Discussion in 'Getting Started' started by MarshallMedia, Apr 19, 2021.

  1. MarshallMedia

    MarshallMedia

    Joined:
    Aug 1, 2020
    Posts:
    11
    Hello, i am in need of some help with my playercontroller script. I was able to program the movements just fine and even figured out how to allow the player to jump, however i have encountered a small problem. The player can press the jump button, space in this case, multiple times and rise indefinitly. I would really like to know what to add to my code in order to only allow the player to jump once while on the ground but not jump while in the air. Here is my code...
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class PlayerController : MonoBehaviour
    5. {
    6.     public Rigidbody rb;
    7.     public float moveSpeed = 10f;
    8.     public Vector3 jump;
    9.     private float xInput;
    10.     private float zInput;
    11.     // Start is called before the first frame update
    12.     void Start()
    13.     {
    14.      
    15.     }
    16.     // Update is called once per frame
    17.     void Update()
    18.     {
    19.         // Good for handling inputs and animaitons
    20.         ProcessInputs();
    21.         if (Input.GetKeyDown("space"))
    22.         {
    23.             Vector3 jump = new Vector3(0.0f, 200.0f, 0.0f);
    24.             GetComponent<Rigidbody>().AddForce(jump);
    25.         }
    26.     }
    27.     void FixedUpdate()
    28.     {
    29.         Move();
    30.         // Movement
    31.     }
    32.     private void ProcessInputs()
    33.     {
    34.         xInput = Input.GetAxis("Horizontal");
    35.         zInput = Input.GetAxis("Vertical");
    36.     }
    37.     private void Move()
    38.     {
    39.         rb.AddForce(new Vector3(xInput, 0f, zInput) * moveSpeed);
    40.     }
    41. }
    If anyone could show me the proper code and possibly explain how it works i would really appreciate it. Thank you.
     
  2. vendaar

    vendaar

    Joined:
    Dec 15, 2012
    Posts:
    37
    You can for example add four raycasts on either edge of the playermodel to see if he is touching the ground or not.

    Code (CSharp):
    1.     //call this when we press the jump button
    2.     void TryJump ()
    3.     {
    4.         //creates four different raycasts to determine if the player is on the ground or not
    5.         Ray ray1 = new Ray(transform.position + new Vector3(0.5f, 0, 0.5f), Vector3.down);
    6.         Ray ray2 = new Ray(transform.position + new Vector3(-0.5f, 0, 0.5f), Vector3.down);
    7.         Ray ray3 = new Ray(transform.position + new Vector3(0.5f, 0, -0.5f), Vector3.down);
    8.         Ray ray4 = new Ray(transform.position + new Vector3(-0.5f, 0, -0.5f), Vector3.down);
    9.  
    10.         bool cast1 = Physics.Raycast(ray1, 0.7f);
    11.         bool cast2 = Physics.Raycast(ray2, 0.7f);
    12.         bool cast3 = Physics.Raycast(ray3, 0.7f);
    13.         bool cast4 = Physics.Raycast(ray4, 0.7f);
    14.         //shoot the raycast
    15.         if (cast1 || cast2 || cast3 || cast4)
    16.         {
    17.             //add force to the jump of player is on the ground
    18.              rig.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
    19.         }
    20.     }
     
    MarshallMedia likes this.
  3. MarshallMedia

    MarshallMedia

    Joined:
    Aug 1, 2020
    Posts:
    11
    Thank you for your reply. I appreciate your time. Could you tell me where and how i should insert this into my current code? I apologize, i am still learning a lot of the basic script functions.
     
  4. vendaar

    vendaar

    Joined:
    Dec 15, 2012
    Posts:
    37
    Hey,
    no problem, im a beginner myself.

    You first need to add a new function called "TryJump()" on the bottom like you seein line 43.
    I modified my code i posted to include your existing jump code.
    Then you call that newly created function when you press the Jump button like i did here in line 24.
    I put some comments onto it so you can understand better whats happening

    Code (CSharp):
    1.   using System.Collections;
    2.     using System.Collections.Generic;
    3.     using UnityEngine;
    4.     public class PlayerController : MonoBehaviour
    5.     {
    6.         public Rigidbody rb;
    7.         public float moveSpeed = 10f;
    8.         public Vector3 jump;
    9.         private float xInput;
    10.         private float zInput;
    11.         // Start is called before the first frame update
    12.         void Start()
    13.         {
    14.    
    15.         }
    16.         // Update is called once per frame
    17.         void Update()
    18.         {
    19.             // Good for handling inputs and animaitons
    20.             ProcessInputs();
    21.             if (Input.GetKeyDown("space"))
    22.             {
    23.             // I integrated your existing jump code into a new function you can find on the bottom, we just call this function here
    24.                 TryJump();
    25.             }
    26.         }
    27.         void FixedUpdate()
    28.         {
    29.             Move();
    30.             // Movement
    31.         }
    32.         private void ProcessInputs()
    33.         {
    34.             xInput = Input.GetAxis("Horizontal");
    35.             zInput = Input.GetAxis("Vertical");
    36.         }
    37.         private void Move()
    38.         {
    39.             rb.AddForce(new Vector3(xInput, 0f, zInput) * moveSpeed);
    40.         }
    41.    
    42.         // New Jump script, you need to call it when you press the jump button
    43.     void TryJump ()
    44.     {
    45.         //creates four different raycasts to determine if the player is on the ground or not
    46.         Ray ray1 = new Ray(transform.position + new Vector3(0.5f, 0, 0.5f), Vector3.down);
    47.         Ray ray2 = new Ray(transform.position + new Vector3(-0.5f, 0, 0.5f), Vector3.down);
    48.         Ray ray3 = new Ray(transform.position + new Vector3(0.5f, 0, -0.5f), Vector3.down);
    49.         Ray ray4 = new Ray(transform.position + new Vector3(-0.5f, 0, -0.5f), Vector3.down);
    50.         bool cast1 = Physics.Raycast(ray1, 0.7f);
    51.         bool cast2 = Physics.Raycast(ray2, 0.7f);
    52.         bool cast3 = Physics.Raycast(ray3, 0.7f);
    53.         bool cast4 = Physics.Raycast(ray4, 0.7f);
    54.         //shoot the raycast
    55.         if (cast1 || cast2 || cast3 || cast4)
    56.         {
    57.             //add force to the jump of player is on the ground
    58.               Vector3 jump = new Vector3(0.0f, 200.0f, 0.0f);
    59.               GetComponent<Rigidbody>().AddForce(jump);
    60.         }
    61.     }
    62.    
    63.     }
     
    stain2319 and MarshallMedia like this.
  5. MarshallMedia

    MarshallMedia

    Joined:
    Aug 1, 2020
    Posts:
    11
    Wow! Hey thanks a lot, i had actually been kind of brute forcing it and almost had my own jump script figured out. Took me a little while but this was what i had come up with through my research and testing.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerController : MonoBehaviour
    6. {
    7.     public Rigidbody rb;
    8.     public float moveSpeed = 10f;
    9.     public Vector3 jump;
    10.     public float jumpForce = 2.0f;
    11.  
    12.  
    13.     bool isGrounded;
    14.  
    15.     private float xInput;
    16.     private float zInput;
    17.  
    18.     // Start is called before the first frame update
    19.     void Start()
    20.     {
    21.      
    22.     }
    23.  
    24.     void OnCollisionStay()
    25.     {
    26.         isGrounded = true
    27.     }
    28.     void OnCollisionExit()
    29.     {
    30.         isGrounded = false;
    31.     }
    32.  
    33.  
    34.     // Update is called once per frame
    35.     void Update()
    36.     {
    37.         // Good for handling inputs and animaitons
    38.         ProcessInputs();
    39.  
    40.         if (Input.GetKeyDown("space") && isGrounded)
    41.         {
    42.             Vector3 jump = new Vector3(0.0f, 200.0f, 0.0f);
    43.             GetComponent<Rigidbody>().AddForce(jump);
    44.             isGrounded = false;
    45.         }
    46.     }
    47.  
    48.  
    49.  
    50.     void FixedUpdate()
    51.     {
    52.         Move();
    53.         // Movement
    54.  
    55.     }
    56.  
    57.     private void ProcessInputs()
    58.     {
    59.         xInput = Input.GetAxis("Horizontal");
    60.         zInput = Input.GetAxis("Vertical");
    61.     }
    62.     private void Move()
    63.     {
    64.         rb.AddForce(new Vector3(xInput, 0f, zInput) * moveSpeed);
    65.     }
    66. }
    67.  
    It actually worked for keeping the player from jumping endlessly like i wanted, however that all changed when the player came in contact with walls and/or game objects. When the player was touching a wall or game object it would allow them to jump endlessly so long as they were touching the wall/object. You've been a big help, but i am curious. Can you tell me what i was doing wrong with this code compared to yours?