Search Unity

Detect Jump only if isGrounded == true;

Discussion in 'Scripting' started by VandalPwoof, May 22, 2017.

  1. VandalPwoof

    VandalPwoof

    Joined:
    Feb 17, 2017
    Posts:
    23
    HI all, I have a script that I am not sure what I am missing. I think I have got what I needed in terms of booleans and player interactions but I do not know what I am missing to make the player cube jump only if it is touching the Ground.

    using UnityEngine;

    public class PlayerController : MonoBehaviour
    {
    public float speed = 10f;
    public float jumpspeed = 5f;
    public bool isGrounded = false;

    void Start()
    {
    isGrounded = false;
    }

    void OnCollisionEnter(Collision hit)
    {
    if (hit.gameObject.CompareTag ("Ground")) {
    isGrounded = true;
    } else {
    isGrounded = false;
    }
    }

    void Update()
    {
    var x = Input.GetAxis("Horizontal") * Time.deltaTime * speed;
    var z = Input.GetAxis("Vertical") * Time.deltaTime * speed;
    transform.Translate(x, 0, 0);
    transform.Translate(0, 0, z);

    if ((Input.GetKey ("space")) && isGrounded == true)
    {
    gameObject.transform.Translate (0, 0.1f, 0);
    }
    }
    }
     
  2. WheresMommy

    WheresMommy

    Joined:
    Oct 4, 2012
    Posts:
    890
    Please use code tags... did you debug.log if your isGrounded is changing?
     
  3. joshmond

    joshmond

    Joined:
    May 28, 2012
    Posts:
    34
    Hey, one way to fix your problem would be to use both OnCollisionEnter() and OnCollisionExit(). Set the "isGrounded" field to true inside OnCollisionEnter() and set it to false in OnCollisionExit(), then inside update just check for those flags.

    Hope this helps


    -Joshmond
     
  4. VandalPwoof

    VandalPwoof

    Joined:
    Feb 17, 2017
    Posts:
    23
    Alright, I found the code tag option. So...how would I interact with the OnCollisionEnter and OnCollisionExit functions that have been created?
    I am still very new at C# coding...

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class PlayerController : MonoBehaviour
    5. {
    6.     public float speed = 10f;
    7.     public float jumpspeed = 5f;
    8.     public bool isGrounded = false;
    9.  
    10.     void Start()
    11.     {
    12.         isGrounded = false;
    13.     }
    14.  
    15.     void OnCollisionEnter(Collision hit)
    16.     {
    17.         if (hit.gameObject.CompareTag ("Ground")) {
    18.             isGrounded = true;
    19.         }
    20.     }
    21.  
    22.     void OnCollisionExit(Collision hit)
    23.     {
    24.             isGrounded = false;
    25.     }
    26.            
    27.     void Update()
    28.     {
    29.         var x = Input.GetAxis("Horizontal") * Time.deltaTime * speed;
    30.         var z = Input.GetAxis("Vertical") * Time.deltaTime * speed;
    31.         transform.Translate(x, 0, 0);
    32.         transform.Translate(0, 0, z);
    33.            
    34.         if ((Input.GetKey ("space")) && isGrounded == true)
    35.         {
    36.             gameObject.transform.Translate (0, 0.1f, 0);  
    37.         }
    38.     }
    39. }
    40. }
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I'm not sure what your most recent question is asking.. "how you interact with them" is not really a thing, per se.. the physics system will notify your script when a collision is entered/exited, and your code will run at those times.
    It's worth noting that your OnCollisionExit doesn't currently check the ground tag, as your Enter one does.

    You can still jump even if you're already jumping (or not on the ground, even)?
     
  6. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,835
    Really the isGrounded "variable" inside the CharacterController is more complex than what you have. Most likely one or more Raycasts are being performed to determine if the character is grounded.
    You might want to consider not re-inventing the wheel and figure out how to use Unity's third person or first person character controller that's part of the Standard Assets.
    https://docs.unity3d.com/Manual/class-CharacterController.html

    Edit:
    Here is the code for determining if the character is grounded in ThirdPersonCharacter:
    Code (csharp):
    1.  
    2. if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
    3.             {
    4.                 m_IsGrounded = true;
    5.             }
    6.  
     
    Gintoky likes this.
  7. VandalPwoof

    VandalPwoof

    Joined:
    Feb 17, 2017
    Posts:
    23
    So I take it I have to modify it to be:
    Code (CSharp):
    1. void OnCollisionExit(Collision hit)
    2. {
    3. if (hit.gameObject.CampareTag ("Ground")) {
    4. isGrounded = false;
    5. }
    OK, so I should probably take a look into this myself. Thanks for providing me some pointers.
     
  8. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ya, if you decided to go with the character controller, that's good, too. I probably should have mentioned that, as well :)
    Whatever you think is fun/best ;)
     
  9. Vollmondum

    Vollmondum

    Joined:
    Sep 19, 2012
    Posts:
    10
    For some reason nobody mentioned being grounded elsewhere, except for the ground itself.
    Moreover entering/exiting colliders could happen on the side and from below, so sorry guys, but you and your help here are pretty much useless, unless the only two things in your games are 1.player and 2.ground XD
     
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Though this thread is nearly a year old, you noticed some good points.
    I've come to find that using : a raycast, an overlap shape, or shape cast (box/capsule) downwards is a lot easier and more reliable. No tagging required, or checking enter/exit, etc..

    That was mentioned in this thread, too (just a few posts up). :)
     
    Vollmondum likes this.
  11. Vollmondum

    Vollmondum

    Joined:
    Sep 19, 2012
    Posts:
    10
    Here's my method:

    Each surface needs 4-5 colliders: floor + floor trigger (that's a little displaced upwards for collision detection sake, in case you're falling too fast), ceiling and walls (one wide or two on each side, optional).

    In my attachment you can find a tile I designed for colliders. Unfortunately you need to manually fit each collider, which is booooring, but effective.

    Player needs a collider sized to feet + two rays directed down from two spots at player collider sides. Here perfect position required.

    Player collider should be slighter lower than player's height, for additional jump spacing when hitting ceilings.

    Hope it answers most questions for those in need :)

    P.S. you need to tag floor with "ground", walls with "wall" and ceiling with "ceiling" tags.
    Raycasting is done in LateUpdate and has fixed length, you set yourself. On raycast "ground" null you get ungrounded. Entering "ground" grounds player.
    On "wall" collision you set player speed to zero, to avoid jitter.
    On "ceiling" collision you set velocity.y to 0

    P.P.S. One year old post, but the only one more or less answering something. So I had to figure thing myself. Spent a few working days for the method. Hope it spares people off the hassle XD
     

    Attached Files:

    Last edited: May 10, 2018