Search Unity

OverlapArea problem

Discussion in '2D' started by MoonJellyGames, Aug 21, 2018.

  1. MoonJellyGames

    MoonJellyGames

    Joined:
    Oct 2, 2014
    Posts:
    331
    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):
    1.     private void AttachPart()
    2.     {
    3.         Collider2D hit = Physics2D.OverlapArea(checkBox.bounds.min, checkBox.bounds.max);
    4.  
    5.         Debug.Log("hit something: " + (hit != null));
    6.  
    7.         Debug.Log("checkbox bounds.min: " + checkBox.bounds.min);
    8.         Debug.Log("BoxCollider.bounds.min: " + box.bounds.min);
    9.  
    10.         if (hit != null)
    11.         {
    12.             Debug.Log(hit.gameObject.name + " " + this.gameObject.layer + " " + hit.gameObject.layer);
    13.         }
    14.     }
    I feel like this should be super simple, but it has me stumped.
     
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    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(...)
     
    MoonJellyGames likes this.
  3. MoonJellyGames

    MoonJellyGames

    Joined:
    Oct 2, 2014
    Posts:
    331
    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):
    1.     void OnDrawGizmosSelected()
    2.     {
    3.         Gizmos.color = Color.blue;
    4.         Gizmos.DrawLine(checkBox.bounds.min, checkBox.bounds.max);
    5.     }
    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. :D

    EDIT: Here's my working code, for anyone who runs into a similar problem.

    Code (CSharp):
    1.     private void AttachPart()
    2.     {
    3.         Collider2D[] hitObjArray = new Collider2D[10];
    4.         ContactFilter2D conFilter = new ContactFilter2D();
    5.         conFilter.NoFilter();
    6.         //Debug.Log("is filtering: " + conFilter.isFiltering);
    7.  
    8.         int numHits = checkBox.OverlapCollider(conFilter, hitObjArray);
    9.  
    10.         Debug.Log("numHits: " + numHits);
    11.  
    12.         foreach(Collider2D col in hitObjArray)
    13.         {
    14.             if (col != null)
    15.                 Debug.Log("hit: " + col.gameObject.name);
    16.         }
    17.     }
     
    LiterallyJeff likes this.