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…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Move_Prot : MonoBehaviour {
public int playerSpeed = 10;
private bool facingRight = false;
public int playerJumpPower = 1250;
private float moveX;
public bool isGrounded;
// Update is called once per frame
void Update () {
PlayerMove ();
}
void PlayerMove () {
//CONTROLS
moveX = Input.GetAxis("Horizontal");
if (Input.GetButtonDown ("Jump") && isGrounded == true){
Jump ();
}
//ANIMATIONS
//PLAYER DIRECTION
if (moveX < 0.0f && facingRight == false) {
FlipPlayer ();
} else if (moveX > 0.0f && facingRight == true) {
FlipPlayer ();
}
//PHYSICS
gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2 (moveX * playerSpeed,gameObject.GetComponent<Rigidbody2D>().velocity.y);
}
void Jump () {
//JUMPING CODE
GetComponent<Rigidbody2D>().AddForce (Vector2.up * playerJumpPower);
isGrounded = false;
}
void FlipPlayer() {
facingRight = !facingRight;
Vector2 localScale = gameObject.transform.localScale;
localScale.x *= -1;
transform.localScale = localScale;
}
void OnCollisonEnter2D (Collision2D col){
if (col.gameObject.tag == "ground") {
isGrounded = true;
}
}
}
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).
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:
void OnCollisonEnter2D (Collision2D col){
if (col.gameObject.tag == "ground") {
isGrounded = true;
}
Debug.Log( "hit the " + col.gameObject.tag);
}
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.
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.
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.
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
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.
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.
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.
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.
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.
private void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("collision");
if (col.gameObject.CompareTag("ground"))
{
Debug.Log("you hit " + "ground");
}
}