Hi, everyone. I’ve been working on a 2D platformer, and we have occasionally run into a problem where the player character can catch themselves on the edge of a solid platform but not register themselves as standing on the floor. The effect of this is that the state of the character is as if they are in mid-air when they are in fact colliding with a floor, but the forces in that state are too low for the character to be moved.
The detection for standing on a floor is handled through raycasts as opposed to the main collider on the player (using the main collider would flag the detection if the player were to press into the side of a wall). The position of this raycast started from the edge of the main collider, but we’ve found that collisions can still occur between two colliders when there is a very slight gap between them (the rigidbody has rotation frozen, so no movement occurs). We have had to adjust the placement of the detection twice so far to avoid this softlocking, but also to ensure that the start of the raycast isn’t too far such that floors are detected when pressing against a wall in mid-air.
Since all we have been doing is adjusting numbers, we cannot be certain that we’ve eliminated what is likely a critical bug. Is there a more certain way that we can handle the detecting if the player is on the floor?
I’ve copied the code that handles the detection here:
int nr_of_rays = 3;
float rayOffsetx = .2f;
float rayOffsety = .95f;
float rayInterval = rayOffsetx*2 / (float)nr_of_rays;
bool wasGrounded = isGrounded;
for (float f = -rayOffsetx; f <= rayOffsetx + (rayInterval / 2.0f); f += rayInterval) { //Check left
Debug.DrawRay ( body.position + new Vector2(f,0), Vector2.down*rayOffsety);
foreach (RaycastHit2D hit in Physics2D.RaycastAll ( body.position + new Vector2(f,0), Vector2.down,rayOffsety)) {
if (hit.collider.CompareTag ("floor") || hit.collider.CompareTag ("noslidefloor")) {
FlagJumping ();
}
}
}