Jumping Problem?

So, I have a cube and a platform, and when it jumps, there’s a problem. The jump is at 3 different heights, but is only set to have one height. It also hits each height at random.

#pragma strict

var leftKey : KeyCode;
var rightKey : KeyCode;
var jumpKey : KeyCode;
var speed : float = 5;
var onGround : boolean;
var jumpHeight : float = 500;

function Update () {
    //Walking Code
    if (Input.GetKey(rightKey)){
        rigidbody2D.velocity.x = speed;
    }
    else if (Input.GetKey(leftKey)){
        rigidbody2D.velocity.x = speed * -1f;
    }
    else {
        rigidbody2D.velocity.x = speed - speed;
    }
   
    if (Input.GetKey(jumpKey) && onGround == true){
        rigidbody2D.AddForce(Vector2.up * jumpHeight);
    }
}

function OnCollisionEnter2D (hitInfo : Collision2D) {
    if (hitInfo.gameObject.tag == "Ground"){
        onGround = true;
    }
}

function OnCollisionExit2D (hitInfo : Collision2D) {
    if (hitInfo.gameObject.tag == "Ground"){
        onGround = false;
    }
}

Forces should only be applied in FixedUpdate. In Update you should set a flag “jump” to true where you currently add the force. Then in FixedUpdate you query whether to jump or not. Apply the force if needed and then set jump to false.

So, I changed that, but now the block flies.

#pragma strict

var leftKey : KeyCode;
var rightKey : KeyCode;
var jumpKey : KeyCode;
var speed : float = 5;
var jump : boolean;
var jumpHeight : float = 250;

function Update () {
    //Walking Code
    if (Input.GetKey(rightKey)){
        rigidbody2D.velocity.x = speed;
    }
    else if (Input.GetKey(leftKey)){
        rigidbody2D.velocity.x = speed * -1f;
    }
    else {
        rigidbody2D.velocity.x = speed - speed;
    }
  
    if (Input.GetKey(jumpKey)){
        jump = true;
    }
}

function FixedUpdate () {
    if (Input.GetKey(jumpKey) && jump == true){
        rigidbody2D.AddForce(Vector2.up * jumpHeight);
        jump = false;
    }
}

If I change Input.GetKey(jumpKey) to Input.GetKeyDown(jumpKey) then it works much better, but if I keep hitting the jump button the block jumps and jumps and jumps. I wanted to get rid of the onGround bool because if the block collided with any walls it could slide up the wall.

EDIT: So I actually was able to get it to work by putting the collision detection with the ground back. The problem is if I touch a wall, and move away from the wall, the game thinks I’m no longer on the ground and sets onGround to false. This can be fixed by jumping off of the wall and landing on the ground.

#pragma strict

var leftKey : KeyCode;
var rightKey : KeyCode;
var jumpKey : KeyCode;
var speed : float = 5;
var jump : boolean = false;
var jumpHeight : float = 250;
var onGround : boolean;

function Update () {
    //Walking Code
    if (Input.GetKey(rightKey)){
        rigidbody2D.velocity.x = speed;
    }
    else if (Input.GetKey(leftKey)){
        rigidbody2D.velocity.x = speed * -1f;
    }
    else {
        rigidbody2D.velocity.x = speed - speed;
    }
   
    //jumpKey is pressed
    if (Input.GetKeyUp(jumpKey)){
        jump = false;
    }
}

function OnCollisionEnter2D (hitInfo : Collision2D) {
    if (hitInfo.gameObject.tag == "Ground"){
        onGround = true;
    }
}

function OnCollisionExit2D (hitInfo : Collision2D) {
    if (hitInfo.gameObject.tag == "Ground"){
        onGround = false;
    }
}

function FixedUpdate () {
    //Jump code
    if (Input.GetKeyDown(jumpKey) && jump == false && onGround == true){
        rigidbody2D.AddForce(Vector2.up * jumpHeight);
        jump = true;
    }
}

I made a small modification, that I didn’t actually test!
You should not query for key inputs in FixedUpdate, because you already to that in Update. The idea behind the jump variable is to query, should jump be performed? If it is true, it means that it was set during the update and during the FixedUpdate it is being applied, but only once.

#pragma strict

var leftKey : KeyCode;
var rightKey : KeyCode;
var jumpKey : KeyCode;
var speed : float = 5;
var jump : boolean = false;
var jumpHeight : float = 250;
var onGround : boolean;

function Update () {
   //Walking Code
   if (Input.GetKey(rightKey)){
     rigidbody2D.velocity.x = speed;
   }
   else if (Input.GetKey(leftKey)){
     rigidbody2D.velocity.x = speed * -1f;
   }
   else {
     rigidbody2D.velocity.x = speed - speed;
   }
   
   //jumpKey is pressed
   if (Input.GetKeyUp(jumpKey && onGround)){
     jump = true;
   }
}

function OnCollisionEnter2D (hitInfo : Collision2D) {
   if (hitInfo.gameObject.tag == "Ground"){
     onGround = true;
   }
}

function OnCollisionExit2D (hitInfo : Collision2D) {
   if (hitInfo.gameObject.tag == "Ground"){
     onGround = false;
   }
}

function FixedUpdate () {
   //Jump code
   if (jump){
     rigidbody2D.AddForce(Vector2.up * jumpHeight);
     jump = false;
   }
}

Alright, so that works but I’m still faced with the problem of the walls determining that I’m onGround and then resetting it when I move.

In 3d, I am usually testing where the contact is and how the normal is, though the normal is not available in 2d. But you can still use the contact to know where it is. As I don’t know how the shape of your character is, you may try different things out.
But in general it is more reliable to check the ground contact withing OnCollisionStay2D.

Changed OnCollisionEnter2D to OnCollisionStay2D, which fixed it. Thank you so much!

EDIT: Actually, there is something I need to change. I touch the side of a ground block and it thinks I am on the ground, and when I am against a wall and I hold the direction towards the wall, the block gets stuck against it.