Physics2D.OverlapCircle() only detects the edges of overlapping colliders

if(Physics2D.OverlapCircle(randomWanderLocation, obstacleAvoidanceRadius, 1 << 14) != null)
                {
                    Debug.Log("Path obstructed, not pathing");
                    state = SkeletonState.idle;
                }
                else
                {
                    Debug.Log("Found somewhere to go");
                    state = SkeletonState.wander;
                    agent.SetDestination(randomWanderLocation);
                }

The overlap does not return any colliders when fully inside the wall’s collider, as in the first picture (drew some gizmos to show the area). However, it DOES return a collider when overlapping the edge of the wall, as in the second picture. Am I misinterpreting how OverlapCircle() is supposed to work?


I’m not sure if OverlapCircle will detect if it is inside a collider. You may want to look at CircleCast instead of overlap for this.

1 Like

What is the wall?

I just learned that a compound collider doesn’t consider the “inside” of the compound as a part of the collider, if it’s set to “edge” rather than “polygon”, so that might be the issue.

There’s also the project-wide “Queries Start In Colliders” setting, but I’m not sure if that applies to overlapCircle.

All of that being said, @Chris-Trueman is correct, you ought to go with a CircleCast. Even if the overlap circle worked the way you want it to, you’d still try to wander through thin walls.

1 Like

Interesting. Yeah, I guess I should have mentioned that there is a composite collider combining all of the walls of this level. Setting the Geometry Type to Polygons seems to have fixed the issue.

Circle cast definitely wouldn’t be good in my case since I want my enemies to pathfind to valid locations that might be behind obstacles. The walls in my levels will definitely be thick enough such that this won’t be an issue, but it’s something I’ll have to manage.

Anyway, thanks so much for the help! This one had me stumped.

No problem!

You can edit the “edge radius” parameter to see what’s going on.

Outline mode produces outlines (edges only) so there isn’t an inside to detect. It essentially produces the same edge primitives as the EdgeCollider2D. Edges in 2D Physics (Box2D) are open shapes even if the start/end points of an edge chain coincide. Polygons, Circles & Capsules are closed shapes and their “inside” is detectable.

The main point being that physics uses these primitives and the Unity components are not involved so it all comes down to Polygons, Circles, Capsules and Edges.

Is there any advantage to using the outline mode that I’m not seeing? For our case (tilemaps), we really want the game to consider the space as a closed shape rather than just edges. We’ve just gone with outline as that’s the default.

Is the outline mode perhaps faster? There might be less data to test against?

Physics performs detections between primitive shapes only (not whole colliders). This means that when moving across different (say) polygons, you can contact edges of them. This is seen as “ghost” collisions and is very common in physics engines.

EdgeCollider2D produces continuous edges as does CompositeCollider2D in outline mode which remove this problem.

Also, Outline mode tends to produce less primitive shapes too. You can see the primitive shape count in the inspector for any collider (open up the Info section).

BTW: The docs mention open/closed shapes and whether collisions/triggers are detected inside or not here.

1 Like

Reading the docs always helps!

I am wondering about this line in the docs for the polygon type:

“This is usually the least efficient geometry to use as it produces multiple shapes or edges. These multiple shapes cause unwanted collisions which is where two separate Colliders get in contact even though both are aligned perfectly”

What exactly are the situations that are described here? I wasn’t quite able to envision it from the text itself.

There’s some pretty good descriptions here:

https://www.iforce2d.net/b2dtut/ghost-vertices

Additionally, any concave outline has to be decomposed into multiple convex polygons producing more primitive shapes to cover the region however due to the above, it isn’t a continuous outline of a concave region so you get ghost collisions. Edge chains (continuous edges) don’t suffer from this.

Take a bunch of BoxCollider2D next to each other which visualy look like their “top” surface produces a continuous surface. It might look that way but it isn’t to the physics system, it’s separate polygons that can contact your collider therefore you might catch side edges and think, “what the hell?!” when your character stops moving or bumps upwards.

If you were to add those colliders to the same CompositeCollider2D then you could merge them together. If you choose Polygon mode then it’s likely to produce a single box out of them but that’s not guaranteed so you might end up with a continuous “top” surface or might not; the gizmos would show this. Also using Polygon mode it (just like the PolygonCollider2D) converts any concave polygons into multiple convex polygons because every closed shape has to be convex.

If however you choose “Outline” then you get continuous edges with the only real downside being that it’s an open shape with no iterior and therefore it can be concave but still continuous. The only limitation (just like the EdgeCollider2D) is that continuous edges should not intersect because it can cause odd collision behaviour.

In short, use Outline mode if you can but understand that the shapes visual “inside” is no different than the “outside” from the physics systems POV.

1 Like

That’s super-helpful, thanks.

Teslagrad had a lot of problems with the character catching on box colliders next to each other in exactly the way you describe. We call it “t-junctions”, since that’s the shape of the outline.

Sounds like I will stick with outlines. It’s probably a much more tractable problem to make sure that my raycasts doesn’t start inside the tilemap than to deal with colliding with flat ground when running on it.

1 Like