Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

How exactly do you implement Collision Filters in ECS?

Discussion in 'Physics for ECS' started by axschacher, Apr 27, 2020.

  1. axschacher

    axschacher

    Joined:
    Mar 14, 2018
    Posts:
    21
    I am trying to get collision filters working with my colliders. Everything was working fine when I was just using CollisionFilter.Default, but when I try to customize it, nothing collides with anything. Having a hard time finding documentation or tutorials dealing with how to create a collision filter using layer masks.

    I do have "CharacterBodies" and "Environment" listed in the layer masks in the inspector.

    I also have the appropriate layer collision matrix set up correctly in project settings, is there a way I can just use that matrix instead of trying to construct the filters manually?

    Any help is much appreciated!

    Code (CSharp):
    1. private static PhysicsCollider MakeCollider()
    2.     {
    3.         CollisionFilter collisionFilter = new CollisionFilter()
    4.         {
    5.             BelongsTo = (uint)LayerMask.GetMask("CharacterBodies"),
    6.             CollidesWith = (uint)LayerMask.GetMask("Environment")
    7.         };
    8.  
    9.         PhysicsMaterial physicsMaterial = PhysicsMaterial.Default;
    10.  
    11.         CapsuleGeometry capsuleGeo = new CapsuleGeometry
    12.         {
    13.             Vertex0 = new float3(0f, 0f, 0f),
    14.             Vertex1 = new float3(0f, 1f, 0f),
    15.             Radius = 1f
    16.         };
    17.  
    18.         return new PhysicsCollider { Value = CapsuleCollider.Create(capsuleGeo, collisionFilter, physicsMaterial) };
    19.     }
     
  2. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    LayerMask is not part of Unity Physics which is likely why the masks don't work out as expected.
    The Unity Physics CollisionFilter logic very similar to that of Box2d.

    Not sure what PhysicsMaterial is either. Is it a local using alias?

    The RagdollDemo shows an example of setting up filters in code.
    The 2c3. Material Properties - Collision Filters demos shows an example of things setup in the editor.
     
    unity_4matez5IL4ysbQ likes this.
  3. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    In order for collision filters to work correctly, all bodies in the scene need to have their BelongsTo and CollidesWith set accordingly. In the collision filters list you can choose from your own defined categories. Index of the category (0-31) represents a power of 2, so if you choose a category with index 3, your value would be 8 (2^3).

    Now, if your layer masks have their defined values, like in your case your collider wants to collide with anything in the layer "Environment", all bodies in that layer need to have their collision filter BelongsTo set to this same value. Otherwise there won't be any collision.

    I hope this helps, let me know if you need further explanations.
     
  4. axschacher

    axschacher

    Joined:
    Mar 14, 2018
    Posts:
    21
    Yes, PhysicsMaterial is a local using alias to not get confused with a Render Material, sorry about that.
    Good to know that layermask is not part of Unity Physics, that must be my problem. I will try looking into those examples, thank you!

    Thank you, yes I was aware of this, I forgot to mention that in my post as something I had ensured was set up correctly as far as I could tell. My environment filter has BelongsTo "Environment" and CollidesWith "CharacterBodies", and vice versa for the CharacterBodies filter.

    I will look into those examples and see where I can get, thanks to you both!

    Edit: Got it working! Here is the working code I ended up with:

    Code (CSharp):
    1. private enum CollisionLayer
    2.     {
    3.         Solid = 1 << 0,
    4.         Character = 1 << 1,
    5.         Item = 1 << 2,
    6.         ItemTrigger = 1 << 3
    7.     }
    8.  
    9.     private static CollisionFilter
    10.         filterSolid = new CollisionFilter()
    11.         {
    12.             BelongsTo =     (uint)(CollisionLayer.Solid),
    13.             CollidesWith =  (uint)(CollisionLayer.Character | CollisionLayer.Item)
    14.         },
    15.         filterCharacter = new CollisionFilter()
    16.         {
    17.             BelongsTo =     (uint)(CollisionLayer.Character),
    18.             CollidesWith =  (uint)(CollisionLayer.Solid | CollisionLayer.ItemTrigger)
    19.         },
    20.         filterItem = new CollisionFilter()
    21.         {
    22.             BelongsTo =     (uint)(CollisionLayer.Item),
    23.             CollidesWith =  (uint)(CollisionLayer.Solid)
    24.         },
    25.         filterItemTrigger = new CollisionFilter()
    26.         {
    27.             BelongsTo =     (uint)(CollisionLayer.ItemTrigger),
    28.             CollidesWith =  (uint)(CollisionLayer.Character)
    29.         };
     
    Last edited: Apr 29, 2020
  5. peterhayman

    peterhayman

    Joined:
    Jan 17, 2023
    Posts:
    3
    Thanks for the post! My problem was not taking seriously the `CollidesWith` field and setting it to all. This is my solution:

    Code (CSharp):
    1. using Unity.Physics;
    2.  
    3. namespace MyApp
    4. {
    5.     public static class PhysicsCategory
    6.     {
    7.         public readonly static uint All = ~0u;
    8.         public readonly static uint Player = 1u << 0;
    9.         public readonly static uint Static = 1u << 1;
    10.         public readonly static uint Dynamic = 1u << 2;
    11.         public readonly static uint Interactor = 1u << 3;
    12.         public readonly static uint Interactable = 1u << 4;
    13.         public static uint Not(uint value) => ~value;
    14.  
    15.         public readonly static CollisionFilter interaction = new CollisionFilter()
    16.         {
    17.             BelongsTo = PhysicsCategory.Interactor | PhysicsCategory.Interactable,
    18.             CollidesWith = PhysicsCategory.Interactor | PhysicsCategory.Interactable,
    19.         };
    20.     }
    21. }