Using multiple raycasts to detect grounded in 2D platformer

I’m currently developing a 2D platformer.

I am using multiple raycasts from the bottom of the player GameObject in order to detect if the player is grounded.

Here’s the code:

rayOffset =0f;

for(int ii =0; ii < numRays; ii++){
   rayOffset += ii ==0? startAndEndOffset : rayInterval;
   rayLoc =newVector3((parentBounds.min.x + rayOffset), rayYLoc);
   Debug.DrawLine(rayLoc,newVector3(rayLoc.x, rayLoc.y - rayLength),Color.magenta);
   RaycastHit2D hit =Physics2D.Raycast(rayLoc,Vector2.down, rayLength, whatIsEnvironment);
   if(hit.collider !=null)
   {
      grounded = true;
      break;
   }
   else{
      grounded = false;
   }
}

My question being, is this best practice? Is there a better way to do this in Unity?

I feel as though I’m missing something, It feels wrong to break out of the for loop early, and this causes the character to act slightly different on left and right ledges.

I’d like to cast all the Rays at the same time and update the grounded status with a bit-wise OR on flags for each ray, but I’m not sure of a clean way to do it in Unity. Any help would be appreciated

Maybe just rearrange the logic so you assume the player is grounded until proven otherwise? Then you have early bail out if you need it.

Something like:

grounded = true;

rayOffset =0f;
for(int ii =0; ii < numRays; ii++){
  rayOffset += ii ==0? startAndEndOffset : rayInterval;
  rayLoc =newVector3((parentBounds.min.x + rayOffset), rayYLoc);
  Debug.DrawLine(rayLoc,newVector3(rayLoc.x, rayLoc.y - rayLength),Color.magenta);
  RaycastHit2D hit =Physics2D.Raycast(rayLoc,Vector2.down, rayLength, whatIsEnvironment);
  if(hit.collider == null)
  {
     grounded = false;
     break;
  }
}

This actually won’t work. When the player is hanging off of the right most or left most edge. The colliders on the edges will have a null collider, and the game will think the player is not grounded, when they are.

You have any ideas on how I could cast the rays at the same time? As a visual representation, let’s say there are n rays, in this case n = 5, if the first and second ray collide there would be something like “11000” where each char/bit is a ray, then I can do a bit-wise OR on all the seperate rays grounded properties to get whether or not the player is grounded.

Does that make sense? It seems like a more robust solution than generating the rays from left to right.

EDIT:

I could make a prefab of a GameObject that contains just a single ray and the logic to detect collisions/grounded, then in the parent (player) I could have a gameObject that contains multiple of these prefabs and instantiate them all at runtime when the Scene starts. Then each ray could have its own generic script that runs and detects collisions, then I can check each one in the parent gameObject that is holding the rays.

Does this sound like good logic? Or am I missing something?

I see - I skimmed your post too quickly. You could definitely create child “sensor” GameObjects that keep track of if they’re touching anything or not. You could also just sum the amount of checks that collide, and if number of collisions == number of rays, you’re definitely grounded.

If you’re trying to differentiate between “left side grounded”, “middle grounded” and “right side grounded”, I’d definitely go with the child sensors.

I’m going to go with the child sensors idea.

@GroZZleR Thanks for your help man, I’ll update this thread when I find a proper solution for this.