Search Unity

'isGrounded' variable will not work properly

Discussion in 'Scripting' started by QuantumCrab, Feb 9, 2018.

  1. QuantumCrab

    QuantumCrab

    Joined:
    Jan 28, 2018
    Posts:
    14
    I wanted to make a game for quite some time now, and only recently (with the help of the 'Lets make a game together tutorial') have I launched into making one. Unfortunately, somewhere in episode 3, he introduces the 'isGrounded' variable. Everything was going fine until he added in a way to get rid of double jumping. At this, my character could not longer jump, as the 'is Grounded' option will not tick when colliding with the ground, meaning that my character cannot jump. The script seems to be identical to what he has in the video, so I am not sure what is wrong...

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Player_Move_Prot : MonoBehaviour {
    6.  
    7.     public int playerSpeed = 10;
    8.     private bool facingRight = false;
    9.     public int playerJumpPower = 1250;
    10.     private float moveX;
    11.     public bool isGrounded;
    12.  
    13.     // Update is called once per frame
    14.     void Update () {
    15.         PlayerMove ();
    16.     }
    17.  
    18.     void PlayerMove () {
    19.         //CONTROLS
    20.         moveX = Input.GetAxis("Horizontal");
    21.         if (Input.GetButtonDown ("Jump") && isGrounded == true){
    22.             Jump ();
    23.         }
    24.         //ANIMATIONS
    25.         //PLAYER DIRECTION
    26.         if (moveX < 0.0f && facingRight == false) {
    27.             FlipPlayer ();
    28.         } else if (moveX > 0.0f && facingRight == true) {
    29.             FlipPlayer ();
    30.         }
    31.         //PHYSICS
    32.         gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2 (moveX * playerSpeed,gameObject.GetComponent<Rigidbody2D>().velocity.y);
    33.     }
    34.  
    35.     void Jump () {
    36.         //JUMPING CODE
    37.         GetComponent<Rigidbody2D>().AddForce (Vector2.up * playerJumpPower);
    38.         isGrounded = false;
    39.     }
    40.          
    41.     void FlipPlayer() {
    42.         facingRight = !facingRight;
    43.         Vector2 localScale = gameObject.transform.localScale;
    44.         localScale.x *= -1;
    45.         transform.localScale = localScale;
    46.     }
    47.  
    48.     void OnCollisonEnter2D (Collision2D col){
    49.         if (col.gameObject.tag == "ground") {
    50.             isGrounded = true;
    51.         }
    52.     }
    53. }
     
    Last edited: Feb 10, 2018
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Please refer to this thread for how to post code nicely on the forums: https://forum.unity.com/threads/using-code-tags-properly.143875/

    It's possible that your ground wasn't tagged correctly as "ground". Either the tag was missing or mispelled (including capitalization).
    Other options to consider if you ever need them might be: a small raycast downward, or an overlap circle (small, just below you).
     
    QuantumCrab likes this.
  3. QuantumCrab

    QuantumCrab

    Joined:
    Jan 28, 2018
    Posts:
    14
    Thanks! I changed it just now. As for the tags, I am quite sure that they were spelt right. So, I might try the raycast option. Thanks a lot!
     
  4. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    You shouldn't need to raycast. This is your first try at debugging your program, which you will do a lot of if you keep programming. The first thing is to find out what is colliding with your player. You do this by typing a debug statement in the OnCollisionEnter2d:
    Code (csharp):
    1.  
    2.  void OnCollisonEnter2D (Collision2D col){
    3. if (col.gameObject.tag == "ground") {
    4.  isGrounded = true;
    5. }
    6. Debug.Log(  "hit the " + col.gameObject.tag);
    7. }
    8.  
    9.  
    Now when the player collides with the ground, it should say " hit the ground" in the console window. If it doesn't, you know something is wrong.

    Also, when the game is running, you should see isGrounded be check marked as true in the editor when you have the player selected and he touches the ground.

    Those things will help you find out why isGrounded isn't changing to true, or if it is, that there is another problem. There is always a reason why your program isn't doing what's expected. You have to find out why. If the object is tagged correctly, spelled right, and actually collides, the program will work.
     
    Last edited: Feb 10, 2018
  5. QuantumCrab

    QuantumCrab

    Joined:
    Jan 28, 2018
    Posts:
    14
    I have used both my original debug code and yours, however when my player touches the object, it still detects no collision, yet the player still lands on the object. The box titled isGrounded still doesn't check no matter what.
     
  6. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    Did it say "hit the" and then nothing? or did it print nothing at all?
    My guess is you need a rigidbody2d on one of the objects, or both. I don't use 2d much. But you may need both a collider2d and a rigidbody2d, so go back through and see if he asks you to add those and how.
     
    Last edited: Feb 10, 2018
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I just wanted to clarify that I offered the other options not because you shouldn't debug why on collision wasn't being called. They were just other ideas. Of course it's a good idea to figure out why something is not working :)
     
  8. QuantumCrab

    QuantumCrab

    Joined:
    Jan 28, 2018
    Posts:
    14
    fire7side, It seems to print nothing. After testing the debug logger, it can print other stuff, so that is not the problem. It is still a problem with the collider.

    methos5k, its a-ok! If this whole collider issue doesn't work, I may still use the raycast.
     
  9. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    To add to this, there are many ways to determine if your character is grounded, none are truly better than others since the best method depends on what needs to be achieved. "Good-enough" can sometimes be better than something applicable to all situations.

    I personally do not like using tags since it is prone to failing simply due to typos, and if you forget to assign the right tags to the right objects it will also fail, and the source of the problem can go un-noticed for a long time. From the way you have replied I also suspect you do not know what a tag is in the context of Unity. Help confirm this by explaining what you know by "tag" in Unity.

    Consider how hard it is to do anything other than a flat plane for your current ground detection as well. As long as the player collides with something tagged ground, regardless of the angle of elevation, it is allowed to jump, which means if you want to create a wall that the player can land on top of eventually, tagging the wall as ground allows the player to wall-jump off the wall. If you do not want the player to wall-jump, this would require you to have a separate collider for the ground for every wall in your game where the player can land on. Far from ideal, but would be good enough for a game like doodle jump where the platforms just float in mid air with no walls to worry about.

    Raycast is in general too small to be used for ground detection. The moment the player's center point is not overlapping the ground when seen from top-down, the player will not be able to jump. This is too small a margin of error for players to work with.
     
  10. QuantumCrab

    QuantumCrab

    Joined:
    Jan 28, 2018
    Posts:
    14
    Just to provide some clarity, these are some screenshots of the game I am trying to make. Screen Shot 2018-02-10 at 5.30.56 pm.png Screen Shot 2018-02-10 at 5.31.23 pm.png
     
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Here's just a small checklist to verify all is well:
    1) at least 1 of the two interacting objects has a non-kinematic rigidbody.
    2) both objects have non-trigger collider
    3) they actually touch (eg: something else, not the ground, isn't preventing your character from touching the ground)

    Useful overview of collisions/triggers matrix: https://docs.unity3d.com/Manual/CollidersOverview.html
    (Scroll down a ways)
     
  12. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    If it prints nothing then your OnCollisionEnter function was never called. That means the problem is related to having a rigidbody, or a collider, or there was no collision.
     
    Last edited: Feb 10, 2018
  13. QuantumCrab

    QuantumCrab

    Joined:
    Jan 28, 2018
    Posts:
    14
    I have tested the code in another project with new objects, and the code still wont work. So it is must be a problem with the code.
     
  14. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    I'll see if I can test it today, but it boils down to just the 2d collision method, because if it was working, it would have printed something, and I can tell you right now, I can't see anything wrong with the code in that method. That just leaves your set up of colliders and rigidbody.
     
    Last edited: Feb 21, 2018
  15. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    OK, I tested this method in a script with an object, a rigidbody, and a collider on the tagged ground, and it worked. See if you can get it to work with your new objects. You don't need any other code. Just see if you can get this method to print "collision" and "you hit the ground". If it doesn't print, it's your set up of tags, rigidbody, or colliders. The ground only needs a collider. The object should be above the ground and fall onto it.

    Code (csharp):
    1.  
    2.     private void OnCollisionEnter2D(Collision2D col)
    3.     {
    4.         Debug.Log("collision");
    5.         if (col.gameObject.CompareTag("ground"))
    6.         {
    7.             Debug.Log("you hit " + "ground");
    8.         }
    9.     }
    10.  
    If you can't get it to work. I would highly recommend going through this tutorial to catch up on basics:
    https://unity3d.com/learn/tutorials...al/introduction-2d-ufo-project?playlist=25844
     
    Last edited: Feb 21, 2018
  16. QuantumCrab

    QuantumCrab

    Joined:
    Jan 28, 2018
    Posts:
    14
    E
    EUREKA!!! It prints! Should I now put in my jump code?

    EDIT: Never mind, I just did and it works.
     
    Last edited: Feb 21, 2018
  17. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    Glad you got it working.
     
  18. QuantumCrab

    QuantumCrab

    Joined:
    Jan 28, 2018
    Posts:
    14
    Thanks to everyone who helped! My character works like a charm. Up next, adding sounds!
    Alright, I guess this thread can be closed by an admin now.
     
  19. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Just so you know, threads don't get closed here when they're "done". They remain, for future visitors/searchers/readers :)
     
  20. QuantumCrab

    QuantumCrab

    Joined:
    Jan 28, 2018
    Posts:
    14
    Oh. Really? Huh, alrighty then. Thanks any way!