Hey all, I'm having a problem getting Physics2D.OverlapArea to work in a way that makes sense to me. All I'm trying to do is check within a rectangular area for an object that can be picked up. In the case my game, the object happens to be the player's arm, which can be removed from his body, thrown, picked-up, and re-attached. Because of this, the arm and the body are on the same physics layer. I could (and may decide to) put the arms on separate layers, but for now, I'm testing by positioning the area check a distance from the body so that it doesn't overlap with it. The weird-looking orange thing is the arm (it's place-holder art, of course). The rectangle around it is where my OverlapArea is supposed to be. The PlayerController script has a public BoxCollider2D that I set in the inspector to the lower BoxCollider2D seen in the inspector. This is how I get my points for the overlap check-- it helps to have a visual on exactly where the area check is. As you can see in my console output, the object found in the OverlapArea check is the zombie body, even though the rectangle is clearly away from the body. You can't see it in the image, but the zombie's box collider is narrow; it's dimensions are a little smaller than the body itself. You may be thinking that the check is hitting the body because my check area is hitting the second box collider, but I have that one disabled when I'm testing. It's only enabled so that you can see it in the screen cap. So, I can't figure out why it's hitting the body instead of the arm. Any ideas? Here's the code: Code (CSharp): private void AttachPart() { Collider2D hit = Physics2D.OverlapArea(checkBox.bounds.min, checkBox.bounds.max); Debug.Log("hit something: " + (hit != null)); Debug.Log("checkbox bounds.min: " + checkBox.bounds.min); Debug.Log("BoxCollider.bounds.min: " + box.bounds.min); if (hit != null) { Debug.Log(hit.gameObject.name + " " + this.gameObject.layer + " " + hit.gameObject.layer); } } I feel like this should be super simple, but it has me stumped.
You could try using checkBox.OverlapCollider(...) and see if you get the same results, or just filter thru the results afterwards for attachable parts. Should be the same results as Physics2D.OverlapAll(...) I would use Debug.DrawLine or something to highlight the hit.point, and verify your assumptions about where things are or what is making contact. You could even set the body to ignore those check colliders with Physics2D.IgnoreCollision(...)
OverlapCollider makes sense as I'm using a box collider anyways. I didn't know about that function, so thanks! I didn't know about IgnoreCollision either-- that's super useful, and I wish I knew about it a long time ago, so thanks again. I've tried to use DrawLine to make sure everything was where it should be, but it wasn't helping. You'll notice the blue diagonal line across my box collider-- that's using this: Code (CSharp): void OnDrawGizmosSelected() { Gizmos.color = Color.blue; Gizmos.DrawLine(checkBox.bounds.min, checkBox.bounds.max); } For whatever reason, the gizmo function is drawing the line appropriately connection the two opposite corners, as expected, but the OverlapArea was not reflecting that. At first, it seemed like OverlapCollider wasn't working either, but I tried using NoFilter on the mandatory ContactFilter2D argument object, and it's actually working. Huzzah! It would be nice to know what the default filter settings are, but I can't seem to find that information in the docs. It's not really a big deal though-- I'll just stick with NoFilter, and then add filters as I deem necessary. Finally, I can proceed. EDIT: Here's my working code, for anyone who runs into a similar problem. Code (CSharp): private void AttachPart() { Collider2D[] hitObjArray = new Collider2D[10]; ContactFilter2D conFilter = new ContactFilter2D(); conFilter.NoFilter(); //Debug.Log("is filtering: " + conFilter.isFiltering); int numHits = checkBox.OverlapCollider(conFilter, hitObjArray); Debug.Log("numHits: " + numHits); foreach(Collider2D col in hitObjArray) { if (col != null) Debug.Log("hit: " + col.gameObject.name); } }