Search Unity

Question How does the group index of a collision filter work exactly?

Discussion in 'Physics for ECS' started by JZ_Focus, Sep 12, 2020.

  1. JZ_Focus

    JZ_Focus

    Joined:
    Nov 19, 2018
    Posts:
    24
    Reading the collision filtering documentation (https://docs.unity3d.com/Packages/com.unity.physics@0.0/manual/collision_queries.html) I thought I understood the use-case for the group index field within the filter.

    The way I saw it, the group index could easily disregard/regard a collider with an equal group index, depending if it is a negative value or a positive value. As the bool method shown in the documentation implies:

    Code (CSharp):
    1. public static bool IsCollisionEnabled(CollisionFilter filterA, CollisionFilter filterB)
    2. {
    3.     if (filterA.GroupIndex > 0 && filterA.GroupIndex == filterB.GroupIndex)
    4.     {
    5.         return true;
    6.     }
    7.     if (filterA.GroupIndex < 0 && filterA.GroupIndex == filterB.GroupIndex)
    8.     {
    9.         return false;
    10.     }
    11.     return
    12.         (filterA.BelongsTo & filterB.CollidesWith) != 0 &&
    13.         (filterB.BelongsTo & filterA.CollidesWith) != 0;
    14. }
    Now for my particular use-case I want to use this group index to make a ray not collide with my personal Physics Collider but I do want it to collide with the Physics Collider of other players. Now each player gets a playerID starting at 1. The way I wanted to do the filtering is by making the group index the negative playerID. This way it would return as false when hitting a collider with the same negative group index (the player's own collider), but it would return true if it was any other negative group index.

    But what I actually get is that my ray either hits me and stops or hits neither me or the enemy and hits the wall behind. I've added a screenshot to hopefully clarify the situation. Groupindex_Case.png
    EDIT: The group index for the red player is actually -1


    I wonder, is there a bug with the current package as it's ofcourse still in preview and prone to errors, is my understanding of group index wrong or is my logic simply wrong.

    Hope someone can clarify!
     
    Last edited: Sep 12, 2020
  2. JZ_Focus

    JZ_Focus

    Joined:
    Nov 19, 2018
    Posts:
    24
    It seems to be resolved by moving the raycast's BelongsTo layer to 2 or even easier to ~0u which is all layers.
     
  3. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    So the way it works is that positive values override BelongsTo/CollidesWith and always enable if they're the same, while negative values always disable. So in your case, you would need a group index of -1 on ray and your character, but that means for other characters you need to use BelongsTo/CollidesWith, since the ray can't have both positive and negative group index. And this behavior is exactly what you achieved with your fix.
     
  4. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
  5. JZ_Focus

    JZ_Focus

    Joined:
    Nov 19, 2018
    Posts:
    24
    Thank you both for the clarifying comments and extra documentation.

    I also kind of ran into something that I'm not sure is supposed to happen. Whenever I have two physics shape exactly on top of each other, the ray will pass the collision, maybe because they must overlap?
    PassThroughExample.PNG
     
  6. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    Not quite sure what you mean. Is the raycast not hitting either body? Is it one body with 2 shapes?
    If you have a small sample scene that might clarify things?
     
  7. JZ_Focus

    JZ_Focus

    Joined:
    Nov 19, 2018
    Posts:
    24
    Yes, the body is not hitting either shape and it is a body with 2 shapes. It has 2 box physics shapes on top of each other, each with a size of 1x1x1. The first box has a position of 0.5 on the y-axis and the other one is -0.5, yet the ray is able to slip through the shapes if it is shot directly at the center of the object. I don't know if that's supposed to happen, as maybe the shapes should always overlap to be sure not to have those scenario's happen.
     
    Last edited: Sep 15, 2020
  8. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    You could be hitting an edge case that the ray is missing both shapes. But could be worth looking into it.
     
  9. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    The ray should certainly hit. Can you show you have the code for your raycast and the settings on the Physics Body|Shape Authoring components? What is the Bevel Radius on the Shape components in particular?

    NVM: I can repro the problem locally
     
    Last edited: Sep 15, 2020
  10. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    So in this case the raycast is running exactly along the planes of the box shapes. We could get into philosophical discussions on whether the raycast should hit. The practical point is that a ray running along the plane will not return a hit.
    If you can't slightly overlap the 2 shapes, then depending on what your actual use case is, I'd suggest using a small sphere collider cast to introduce some thickness to your ray.
     
  11. JZ_Focus

    JZ_Focus

    Joined:
    Nov 19, 2018
    Posts:
    24
    Alright, I was just wondering if it was intended or not as it was something I ran into while testing out why my ray didn't hit what I thought it would hit. Thank you for immediately investigating and clarifying!

    Also, I was wondering, in the DOTS Sample, the shooting is done by a custom HitCollision.Query which has logic in it to determine if an environment was hit or a player was hit. Do you know by any chance if this was because of an early physics package or is that needed because of something else (like it being a multiplayer game)? Maybe I shouldn't be asking this question in this same thread, but I feel it stil pertains to if I should be using the group index within the filter of the ray or a similar HitCollision.Query as the DOTS Sample example.