Physics2D.OverlapCollider requires Collider GameObject to be active. Alternatives?

My trigger/collider setups were starting to get a bit messy so I was testing out some alternatives.

One of the things I wanted to do was check for custom 2D shape collisions during short melee attacks, but I’d also do use something similar for interaction as well.

Instead of listening for Unity messages from colliders that I turn on and off, I wondered if I could set up the collider shapes, disable the GameObject and use call Physic2D.OverlapCollider myself instead.

Turns out it OverlapCollider doesn’t work unless the GameObject that the PolygonCollider2D is on is active in the hierarchy.

Are there better ways to achieve what I’m trying to do with Unity 2D physics? I’m just checking for collisions in a short span of time but it’s a custom 2D polygon shape.

It’s not really doing this for performance reasons. I just want to keep code and the hierarchies readable and avoid a mess of physics layers and having to keep track of a lot of them as I go through testing different game mechanics.

Well yes, the collider has to have actual physics shapes to work i.e. be active/enabled.

You haven’t really described anything in any useful detail why you cannot use shape queries, like OverlapCircle, OverlapBox etc.

If the collider is attached to a Rigidbody2D (probably best to use a Kinematic body-type) that has its Simulated property turned-off (so it isn’t used in the simulation) then I believe it should still work with queries such as OverlapCollider. Know you can just call this on the Rigidbody2D.OverlapCollider to check all colliders, Collider2D.OverlapCollider to check that collider etc. Note if you’re moving this, as alway with physics, do it via the Rigidbody2D i.e. Rigidbody2D.position.

I’m not really following this because it’s kind of vague. Maybe what you’re doing isn’t a good approach but I don’t understand the problem TBH.

Although the reason is not entirely clear, I personally don’t need to know why having a custom 2D shape is important for you. I think for you, I can imagine the solution would be to have a collider that is always active. To prevent it from inadvertently interacting with anything, you could do some combination of setting it as trigger, placing it in a child object and changing its layer that is turned off against all other layers in the layer collision matrix of your Physics2D project settings.

For myself, I have the same issue with trying to use Physic2D.OverlapCollider and it seems unintuitive to me that it would require an active collider where as OverlapBox or OverlapCircle or Overlap anything else would not. I’m working on a script that uses PrefabUtility.InstantiatePrefab to spawn a bunch of prefabs in the editor. I would want the user to be able to specify a custom 2D shape that is used to check proximity to specified layers. My current workaround is as follows:

GameObject colliderObject = new GameObject("TemporaryCollider");
colliderObject.transform.position = position;
Collider2D colliderCopy = colliderObject.AddComponent(settings.collider2D.GetType()) as Collider2D;
EditorUtility.CopySerialized(settings.collider2D, colliderCopy);
Collider2D[] results = new Collider2D[1];
colliderCopy.OverlapCollider(settings.contactFilter2D, results);
DestroyImmediate(colliderObject.gameObject);
return results[0];

If you want a Collider that is not part of the simulation but you want to use its details for queries (or anything else) then simply add a GameObject with the Collider(s) and add a Rigidbody2D with its Simulated flag disabled; you might also set its body-type to Static while you’re at it too although it makes no real difference.

That way, there’s no need to worry then about layers or anything else. If you want to position it, just set the Rigidbody2D.position/.rotation and then query. Ignore the Transform, it has no role here. You can keep this around then to reuse it. You can even keep a set of colliders on it and only use a selected one. None of them will be part of the simulation or get in the way at all.

This is what I described above and it works, fast and without serialization and garbage.

What you’re doing above is extremely expensive and nobody should ever want to do that kind of stuff. Especially so creating an array just to throw it away. Reuse and try to use the List overload where you can.

1 Like