Ray-casting corners

I am doing a 2d plat former and I am using raycasts for collision detection. I am currently trying to fix an issue with angled corners. Originally I would have 5 rays test the x axis for collision but this becomes a problem with corners because the ray doesn’t realize that there is an object in front. This is most noticeable when the player is moving horizontally and vertically.

So I decided to use a lot of rays instead which “fixes” the problem My question is will this cause a significant decrease in performance? If so does anyone know a better method to approach this problem

Can you do a capsule cast instead of a ray cast? Sort of looks like what you’re going for anway

Raycasts are generally pretty cheap, but you can do sweeptests with rigidbodys, or do casts of primitive shapes instead of just a ray.

Some examples

Well since I’m using the 2d engine circle cast would be the only possible option. But why would I want to use a circle cast. My current method is along the lines of if the ray returns true it will snap the player next to the wall, I’m not sure if a circle cast would reliable for this.

Also I should note I’m not using rigid bodies at all.
Here is a snippet of my code

 for (int i = 0; i < horiRayCount; i++)
            {
                rayOrigin = originalOrigin + (Vector2.up * (horiRaySpaceing * i));
                hit = Physics2D.Raycast(rayOrigin, direction * Vector2.right,
                    actualLength + skinWidth, collisionMask);
                if (hit.distance != 0 && hit.distance < rayLegnth && hit.collider != null && hit.collider.tag == platformTag)
                {
                    actualLength = (hit.distance-skinWidth) * Time.deltaTime;
                    rayLegnth = hit.distance;
                    collision = true;
                }
                if (i == 0 && collision)//check for steping
                {
                    //testing current problem without this add this later
                    step = upStep(hit.distance, horiRaySpaceing, horiRayCount, direction, originalOrigin, skinWidth, collisionMask, platformTag);
                   if (step) { speed.x = speed.y = 0.0F; return; }
                }

               Debug.DrawRay(rayOrigin, Vector2.right *direction* actualLength, Color.red);
            }
            if (collision)
            {
                Debug.Log("horizontal collision");

                transform.Translate(direction * (rayLegnth - skinWidth ), 0, 0);

At the very least you could early-out of the loop when you hit something

int i = 0;
while (!collision && i < horiRayCount)
{
  // do your thing
  i++;
}

There’s more than just circle cast. Checkout the entire Physics2D documentation:

There’s BoxCast, BoxcastAll, BoxCastNonAlloc, LineCast, OverlapArea, etc… I’m guessing you want to use BoxCast. I just said CircleCast as an example since I wasn’t sure your exact use case.

You should just be able to replace that entire for loop with a single Boxcast. I haven’t gone line-by-line, but something like this.

Vector3 endCastPosition = originalOrigin + (ActualLength + skinWidth) * Vector2.right;
RaycastHit2D hit = Physics2D.BoxCast(originalOrigin, endCastPosition, collisionMask;
if (hit != null)
{
  actualLength = hit.distance - skinWidth;
  castLength = hit.distance;
  collision = true;
}

can’t do that it can cause problems if the first thing you hit is farther than something else above

Thank you for the help but I don’t think that will work well enough. From what I can understand it will return true if there is a collision with another collider. However I imagine it will cause problems if it overlaps multiple shapes at different heights and x axis positions at once.
I am by no means a pro but I doubt the box cast was made with this problem in mind

It returns a RaycastHit2D with information about the collision. Or null if there is no collision.

If you’re worried about multiple colliders, you can BoxCastAll and get all the colliders with all their different hit points.

Is there something I’m missing about what you need?

I guess I’ll give it a try for today.

Just one last question if the box collider overlaps multiple objects at once what will happen? Will it return the point that is closest in the x direction.
I guess I’m just having some trouble understanding the specifics on the box cast, guess I’ll just do some testing best way for me to understand.

Thanks for all the help by the way

If you do box cast all, it will keep going even after the first hit. As it goes it tracks what colliders it is hitting, where the cast hit the collider, then returns an array filled with RaycastHit2D with all the hit points.

I believe it’ll return one RaycastHit2D per collider that the boxcast comes across. Documentation even says it’s sorted by distance.

[quote]
Just one last question if the box collider overlaps multiple objects at once what will happen? Will it return the point that is closest in the x direction.
[/quote]Not exactly sure what you are asking, I believe if the box is already overlapping when you do the boxcast, then it won’t detect anything it is already overlapping. You might be able to use OverlapBox but I don’t think it’s rotatable.

So the boxcast shouldn’t be doing any overlapping. I believe it should return contact points. I would need to do some testing to see exactly how this works out (say dropping a flat box on flat surface. I have no idea what would be picked for the contact point.)

Well I would like to thank you for the help with a different method but I just realized that I had a brain fart and all it took were two easy fixes.
The first was setting up an if statement if there is a collision
The second was the fact that I was dumb and multiplied actual ray length by time when I shouldn’t have.
So it works fine and I’m happy with it.

1 Like