Search Unity

Check if character is grounded?

Discussion in 'Scripting' started by Silvan, Apr 28, 2014.

  1. Silvan

    Silvan

    Joined:
    Apr 23, 2014
    Posts:
    24
    Hey Community
    I use this script to make a jump n run.. but the problem is : when i press jump and he is in mid air i can press again and he jumps from mid air. So he gets higher and higher... He should only can jump after he hits the ground...
    This is my script:

    using UnityEngine;
    using System.Collections;

    public class PlayerMovement : MonoBehaviour {

    private bool grounded;

    private float speed;

    private Vector2 startPos;

    //
    void Start () {

    speed = 7;

    grounded = true;

    }


    //
    void FixedUpdate ()
    {

    transform.Translate(-Vector3.forward * -speed * Time.deltaTime);//

    #if UNITY_EDITOR

    transform.Translate (Vector2.right * Input.GetAxis ("Horizontal") * 5 * Time.deltaTime);
    if (Input.GetKey (KeyCode.Space) grounded == true)
    {
    rigidbody.AddForce (0,50,0,ForceMode.Force);
    grounded = true;

    }
    #endif
    #if UNITY_ANDROID
    transform.Translate (Vector3.right * Input.acceleration.x * 7.5f * Time.deltaTime);
    if (Input.touchCount > 0)
    {

    Touch touch = Input.touches [0];


    switch (touch.phase)

    {

    case TouchPhase.Began:
    startPos = touch.position;
    break;


    case TouchPhase.Moved:
    if (Mathf.Abs (touch.position.y - startPos.y) > 100) //

    {

    float swipeValue = Mathf.Sign (touch.position.y - startPos.y);

    if (swipeValue > 0 grounded == true) //
    {
    rigidbody.AddForce (0,50,0,ForceMode.Force);
    grounded = true;
    break;
    }
    else if (swipeValue < 0) //
    { //
    break;
    }
    }
    break;
    }
    }
    #endif
    }
    }
     
  2. SmokyZebra

    SmokyZebra

    Joined:
    Mar 13, 2014
    Posts:
    139
    It's happening because when u jump you set grounded to true, so you can jump again. Change those line to grounded = false when jumping and add a if statement in your update function checking height of your player to set back grounded to true. Or add a OnCollisionEnter function checking collision with ground to set back grounded to true.
     
    Last edited: Apr 28, 2014
  3. Silvan

    Silvan

    Joined:
    Apr 23, 2014
    Posts:
    24
    i changed it, and now i cant jump even once...
    could u may copy my scrip, and put in what i need to change?
    Im really bad at scripting...
     
  4. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    Hey there,

    You most likely want to do a Raycast downwards to see if you are grounded. Add something like this in your FixedUpdate:

    Code (csharp):
    1.  
    2. grounded = Physics.Raycast(transform.position, Vector3.down, .5f);
    3.  
    This draws a line from where the player is to .5 down. If it hits, thus we are not far from the ground, it returns true. You might have to tweak the .5f to be smaller/bigger, depending on the scale of your scene.
     
    Last edited: Apr 28, 2014
    SaltMKII likes this.
  5. Silvan

    Silvan

    Joined:
    Apr 23, 2014
    Posts:
    24
    Like this?

    using UnityEngine;
    using System.Collections;

    public class PlayerMovement : MonoBehaviour {

    private bool grounded;

    private float speed;

    private Vector2 startPos;

    //
    void Start () {

    speed = 7;

    grounded = true;

    }

    //
    void FixedUpdate ()
    {

    transform.Translate(-Vector3.forward * -speed * Time.deltaTime);//

    #if UNITY_EDITOR

    transform.Translate (Vector2.right * Input.GetAxis ("Horizontal") * 5 * Time.deltaTime);
    if (Input.GetKey (KeyCode.Space) grounded == true)
    {
    rigidbody.AddForce (0,50,0,ForceMode.Force);
    grounded = true;
    grounded = Physics.Raycast(transform.position, Vector3.down, .5f);
    }
    #endif
    #if UNITY_ANDROID
    transform.Translate (Vector3.right * Input.acceleration.x * 7.5f * Time.deltaTime);
    if (Input.touchCount > 0)
    {

    Touch touch = Input.touches [0];


    switch (touch.phase)

    {

    case TouchPhase.Began:
    startPos = touch.position;
    break;


    case TouchPhase.Moved:
    if (Mathf.Abs (touch.position.y - startPos.y) > 100) //

    {

    float swipeValue = Mathf.Sign (touch.position.y - startPos.y);

    if (swipeValue > 0 grounded == true) //
    {
    rigidbody.AddForce (0,50,0,ForceMode.Force);
    grounded = true;
    break;
    }
    else if (swipeValue < 0) //
    { //
    break;
    }
    }
    break;
    }
    }
    #endif
    }
    }

    This dont even let me jump?
    Im sorry im really bad at scripting... could u copy my script and put it in where u think it should work?
    Thank u
     
  6. SmokyZebra

    SmokyZebra

    Joined:
    Mar 13, 2014
    Posts:
    139
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerMovement : MonoBehaviour {
    5.  
    6. private bool grounded;
    7.  
    8. private float speed;
    9.  
    10. private Vector2 startPos;
    11.  
    12. //
    13. void Start () {
    14.  
    15. speed = 7;
    16.  
    17. grounded = true;
    18.  
    19. }
    20.  
    21.  
    22. //
    23. void FixedUpdate ()
    24. {
    25.  
    26. transform.Translate(-Vector3.forward * -speed * Time.deltaTime);//
    27.  
    28. if(transform.position.y < 1){
    29. grounded = true;
    30. }
    31.  
    32. #if UNITY_EDITOR
    33.  
    34. transform.Translate (Vector2.right * Input.GetAxis ("Horizontal") * 5 * Time.deltaTime);
    35. if (Input.GetKey (KeyCode.Space)  grounded == true)
    36. {
    37. rigidbody.AddForce (0,50,0,ForceMode.Force);
    38. grounded = false;
    39.  
    40. }
    41. #endif
    42. #if UNITY_ANDROID
    43. transform.Translate (Vector3.right * Input.acceleration.x * 7.5f * Time.deltaTime);
    44. if (Input.touchCount > 0)
    45. {
    46.  
    47. Touch touch = Input.touches [0];
    48.  
    49.  
    50. switch (touch.phase)
    51.  
    52. {
    53.  
    54. case TouchPhase.Began:
    55. startPos = touch.position;
    56. break;
    57.  
    58.  
    59. case TouchPhase.Moved:
    60. if (Mathf.Abs (touch.position.y - startPos.y) > 100) //
    61.  
    62. {
    63.  
    64. float swipeValue = Mathf.Sign (touch.position.y - startPos.y);
    65.  
    66. if (swipeValue > 0  grounded == true) //
    67. {
    68. rigidbody.AddForce (0,50,0,ForceMode.Force);
    69. grounded = false;
    70. break;
    71. }
    72. else if (swipeValue < 0) //
    73. { //
    74. break;
    75. }
    76. }
    77. break;
    78. }
    79. }
    80. #endif
    81. }
    82. }

    you may need to change the value in the if statement i added. I have put 1 but i don't know how your level is set, so i don't know the height of your player and terrain.

    Code (csharp):
    1. if(transform.position.y < 1){
    2. grounded = true;
    3. }
    If you have different height in terrain, this won't work and you'll need to replace that if statement by a OnCollisionEnter function (dont put it in the update function). I'm more used to Unity script so here it goes in Javascript, u'll have to translate it to C# . By the way, if u're bad at scripting, u should really script in JS instead of C#, it's a bit easier and more clear to read:


    Code (csharp):
    1. function OnCollisionEnter ( hit : Collision ){
    2.     if(hit.gameObject.tag == "Ground"){
    3.       grounded = true;
    4.              
    5.        }
    6.            
    7.      }    
    8. }
    for that function to work, you need to add the tag Ground to your ground, and make sure that your ground and your player have a collider and at least one have a rigidbody.
     
    Last edited: Apr 28, 2014
  7. Silvan

    Silvan

    Joined:
    Apr 23, 2014
    Posts:
    24
    Hmm it just let me jump once maybe a mm high :(
    This is not my script i took it from a tutorial...
    I want to make a game with controls like temple run but without the script for the controls i cant iven start...
    Its a school project...
     
  8. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    If you put the raycast check inside the IF we'd only check if we where grounded when the button is down. This is incorrect, we want to always check. When we know if we are grounded or not, we check if we are and if the space key is down, then jump.

    Code (csharp):
    1.  
    2. void FixedUpdate ()
    3. {
    4.    transform.Translate(-Vector3.forward * -speed * Time.deltaTime);
    5.    grounded = Physics.Raycast(transform.position, Vector3.down, .5f);
    6.  
    7.    if (grounded  Input.GetKeyDown (KeyCode.Space))
    8.    {
    9.        rigidbody.AddForce (0,50,0,ForceMode.Force);
    10.    }
    11. }
    12.  
    13.  
     
  9. SmokyZebra

    SmokyZebra

    Joined:
    Mar 13, 2014
    Posts:
    139
    How long do you have to make your game ? Making a game is really time consumming, AAA games are made in 2 or 3 years with 30 or more people working on it full time. Don't expect to make a great game if you have like one month to make it and do others stuffs at the same time. And you really need to learn scripting to make a game, because each game is different so you will have, at least, to tweak the code you find.
     
  10. Silvan

    Silvan

    Joined:
    Apr 23, 2014
    Posts:
    24
    U mean like this:?
    using UnityEngine;
    using System.Collections;

    public class PlayerMovement : MonoBehaviour {

    private bool grounded;

    private float speed;

    private Vector2 startPos;

    //
    void Start () {

    speed = 7;

    grounded = true;

    }


    //
    void FixedUpdate ()

    {
    #if UNITY_EDITOR
    transform.Translate (-Vector3.forward * -speed * Time.deltaTime);

    grounded = Physics.Raycast (transform.position, Vector3.down, .5f);



    if (grounded Input.GetKeyDown (KeyCode.Space)) {

    rigidbody.AddForce (0, 50, 0, ForceMode.Force);

    }
    }
    #endif
    #if UNITY_ANDROID
    transform.Translate (Vector3.right * Input.acceleration.x * 7.5f * Time.deltaTime);
    if (Input.touchCount > 0)
    {

    Touch touch = Input.touches [0];


    switch (touch.phase)

    {

    case TouchPhase.Began:
    startPos = touch.position;
    break;


    case TouchPhase.Moved:
    if (Mathf.Abs (touch.position.y - startPos.y) > 100) //

    {

    float swipeValue = Mathf.Sign (touch.position.y - startPos.y);

    if (swipeValue > 0 grounded == true) //
    {
    rigidbody.AddForce (0,50,0,ForceMode.Force);
    grounded = true;
    break;
    }
    else if (swipeValue < 0) //
    { //
    break;
    }
    }
    break;
    }
    }
    #endif
    }
    }

    this gives me an error...
     
  11. Silvan

    Silvan

    Joined:
    Apr 23, 2014
    Posts:
    24
    I have maybe 2 months for it... It shouldnt be a perfect game.. the character should just run automaticly and jump when u want but only when he is on the ground.. and if he touches a wrong object the game should restart(this i want to make after i fixed this jump error...)
     
  12. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    Can you please post code in
    Code (csharp):
    1.  [ /code] tags?
    2.  
    3. Errors are very, very valuable. What is the error you are seeing, what does it tell you?
     
  13. Silvan

    Silvan

    Joined:
    Apr 23, 2014
    Posts:
    24
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerMovement : MonoBehaviour {
    5.    
    6.     private bool grounded;
    7.    
    8.     private float speed;
    9.    
    10.     private Vector2 startPos;
    11.    
    12.     //
    13.     void Start () {
    14.        
    15.         speed = 7;
    16.        
    17.         grounded = true;
    18.        
    19.     }
    20.    
    21.    
    22.     //
    23.         void FixedUpdate ()
    24.  
    25.         {
    26.         #if UNITY_EDITOR   
    27.                 transform.Translate (-Vector3.forward * -speed * Time.deltaTime);
    28.    
    29.                 grounded = Physics.Raycast (transform.position, Vector3.down, .5f);
    30.            
    31.            
    32.            
    33.                 if (grounded  Input.GetKeyDown (KeyCode.Space)) {
    34.                
    35.                         rigidbody.AddForce (0, 50, 0, ForceMode.Force);
    36.                
    37.                 }
    38.         }
    39.         #endif
    40.         #if UNITY_ANDROID
    41.         transform.Translate (Vector3.right * Input.acceleration.x * 7.5f * Time.deltaTime);
    42.         if (Input.touchCount > 0)
    43.         {
    44.            
    45.             Touch touch = Input.touches [0];
    46.            
    47.            
    48.             switch (touch.phase)
    49.                
    50.             {  
    51.                
    52.             case TouchPhase.Began:
    53.                 startPos = touch.position;
    54.                 break;
    55.                
    56.                
    57.             case TouchPhase.Moved:
    58.                 if (Mathf.Abs (touch.position.y - startPos.y) > 100) //
    59.                    
    60.                 {
    61.                    
    62.                     float swipeValue = Mathf.Sign (touch.position.y - startPos.y);
    63.                    
    64.                     if (swipeValue > 0  grounded == true) //
    65.                     {
    66.                         rigidbody.AddForce (0,50,0,ForceMode.Force);
    67.                         grounded = true;
    68.                         break;
    69.                     }
    70.                     else if (swipeValue < 0) //
    71.                     {    //
    72.                         break;
    73.                     }
    74.                 }
    75.                 break;
    76.             }
    77.         }
    78.         #endif
    79.     }
    80. }
    Im sorry i didnt knew that..
    the error is: error cs1519 unexpected symbol `(' in class, struct or interface member declaration