Multiple Colliders Issue

Hello,

I have a question I need answered asap.

So basically my script is used to tell if the player is grounded or not. I used a collider to tell if the collider is grounded. However, I have come into a problem. Since the cube can rotate, i need to have the collider on every edge. So heres my problem. When I am next to a wall, I can double jump, triple jump, quadripual jump, well keep jumping untill I get off the wall. I have made a temporary fix by telling my script to make all objects which have a certain tag (“notag”) on them, to make the cube not able to count them as a collider and to make grounded = false when they touch. This did somewhat solver my problem but lets say my cube is next to the wall, then the cube wont be able to jump because grounded is off when touching the wall. I want to make this script as dynamic as it can be so please help me.

#pragma strict
var speed : float = 20;
var jump : float = 5000;
var grounded = false;
function Start () {
 
 
}

function OnCollisionStay2D(other : Collision2D) {
if(other.gameObject.tag == "notag") {
grounded = false;
}
else {
grounded = true;
}
}
//BUG FIX : When touching notag, the player cant jump at all.  Need it to see that there is a zone the player can jump at.
function OnCollisionEnter2D(other : Collision2D) {
if(other.gameObject.tag == "notag"){
grounded = false;
}
else {
grounded = true;
}
}


//BUG FIX : When player has collided with two objects and one collision leaves, grounded is false.
function OnCollisionExit2D(other : Collision2D) {
grounded = false;
}




 
function Update () {
if(Input.GetKey("d")) {
rigidbody2D.AddForce (Vector2(1, 0) * speed);
//transform.Translate(Vector3.right * Time.deltaTime * 10);
}
if(Input.GetKey("a")) {
rigidbody2D.AddForce (Vector2(-1, 0)* speed);
//transform.Translate(Vector3(-speed,0,0) * Time.deltaTime);
//transform.Translate(Vector3.left * Time.deltaTime * 10);
}
if(Input.GetKeyDown("space")){
	if(!GravitySwitch.isOn){
	if(grounded){

rigidbody2D.AddForce (Vector2(0, 1) * jump);
}
}
if(GravitySwitch.isOn){
if(grounded){
rigidbody2D.AddForce (Vector2(0, -1.2) * jump);
}
}
 

}
if(Input.GetKey("q")){
rigidbody2D.AddTorque (7.5);
}
if(Input.GetKey("e")){
rigidbody2D.AddTorque (-7.5);
}
}

Create a Collision for your ground and in ground OnCollisionEnter2D change your grounded = false and on OnCollisionExit2D change grounded = true .

Try casting rays that their length is like a block or a bit longer than a block size. For example, cast three rays, one from toe of your character through the ground, one from his middle and one from his back. Does this help?

The way I approached this was with Linecast. And it allowed me to have many options for queueing different animation states, such as edge balance or slope detection.

First, for a single linecast, I create two Empty GameObjects, one is the Start Position of the Linecast, the other is the End Position. These two objects are children of my Player. For example, I’d have one Linecast for the right foot, or right side of my Player. The groundR_start object would be positioned within my player collider, on it’s right edge, and the _end object would be place below my collider, but still aligned with the right edge. This would detect when only the bottom right of my collider is touching ground.

Then in the script I create a Transform variable for them:

	private Transform groundCheckL_start;
	private Transform groundCheckL_end;
	private Transform groundCheckM_start;
	private Transform groundCheckM_end;
	private Transform groundCheckR_start;
	private Transform groundCheckR_end;

//Also, Bool's to contain the result of these Linecast's.
	public bool groundedL;
	public bool groundedM;
	public bool groundedR;

And then assign them:

Start(){
	groundCheckL_start = transform.Find("groundL_start");
	groundCheckL_end = transform.Find("groundL_end");
	groundCheckM_start = transform.Find("groundM_start");
	groundCheckM_end = transform.Find("groundM_end");
	groundCheckR_start = transform.Find("groundR_start");
	groundCheckR_end = transform.Find("groundR_end");
}

Now, in my Update() function, I can use Linecast to detect which one’s are hitting “Ground”.

groundedR = Physics2D.Linecast(groundCheckR_start.position, groundCheckR_end.position, 1 << LayerMask.NameToLayer("Ground"));
groundedM = Physics2D.Linecast(groundCheckM_start.position, groundCheckM_end.position, 1 << LayerMask.NameToLayer("Ground"));
groundedL = Physics2D.Linecast(groundCheckL_start.position, groundCheckL_end.position, 1 << LayerMask.NameToLayer("Ground")); 

Then you can simply use these 3 Bool’s to determine if you’re allowed to do something, like Jump. If at least one of them = true, then you probably want to let the player jump. And if say only groundedR is true, the player would play the balancing animation.