Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

collision grouping challenge

Discussion in 'Physics for ECS' started by snacktime, Jul 16, 2021.

  1. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    I'll be specific in case there is another angle here I'm missing.

    scene with multiple boats and a single terrain. And then a random number of dynamic box colliders that can also be intersecting the water level and hence collide with boats.

    The catch is we are simulating multiple client scenes in a single simulation server side, probably close to 2k per simulation instance that's the target. The numbers are not huge several hundred boats and box colliders max, around 40 unique terrains.

    So the boats and dynamic boxes should only collide if they correspond to the same client scene instance. And then the boats should collide with just one specific terrain.

    Groups can solve boats and boxes. Put them both in the same group associated with the client scene instance.

    Terrains I don't know.

    Run a job to disable collision pairs I could do. But that seems potentially expensive. And by default we have all those terrains at the same height with boats colliding with all of them potentially.

    If I optimize the terrains for the server I could just create the edge areas. So the height would always be capped and I don't need more then around 5m of height. So then I could stick every unique terrain at a different height. I'm guessing this is going to make collision handling cheaper also since there would be far fewer contacts to resolve?

    I'm also curious in theory which would be cheaper. The terrain collider or say a number of box colliders placed around the terrain edge area, and also combined into a single compound per terrain. If I do that what is the cheapest basic collider type to resolve?
     
    BeerCanAI likes this.
  2. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    You could make a custom copy of the Unity Physics code and tweak the CollisionFilter.IsCollisionEnabled function to suit your needs (see com.unity.physics\Unity.Physics\Collision\Filter\CollisionFilter.cs). Maybe tweak the GroupIndex to be a Client instance number and disable collision for anything that doesn't have the same GroupIndex

    e.g
    Code (CSharp):
    1.         public static bool IsCollisionEnabled(CollisionFilter filterA, CollisionFilter filterB)
    2.         {
    3.             if (filterA.GroupIndex != filterB.GroupIndex)
    4.             {
    5.                 return false;
    6.             }
    7.             return
    8.                 (filterA.BelongsTo & filterB.CollidesWith) != 0 &&
    9.                 (filterB.BelongsTo & filterA.CollidesWith) != 0;
    10.         }
    11.  
    This would work for terrains, boats and boxes. I'm assuming terrains are static so they won't be colliding with each other anyway.
     
  3. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Ya I was looking at how customizing that might work. And we already have the package in dev mode to expose some internal structures. But there is a misunderstanding I think on the terrains. There isn't a unique terrain per client instance. There is a limited set of unique terrains shared over a larger number of client instances.

    So something like this seems like it should work. Terrains and boats would have a TerrainIndex > 0.

    Plus an additional line in CreateUnion for TerrainIndex.

    Code (csharp):
    1.  
    2.  public static bool IsCollisionEnabled(CollisionFilter filterA, CollisionFilter filterB)
    3.         {
    4.             if (filterA.TerrainIndex > 0 && filterA.TerrainIndex == filterB.TerrainIndex)
    5.             {
    6.                 return true;
    7.             }
    8.             if (filterA.GroupIndex > 0 && filterA.GroupIndex == filterB.GroupIndex)
    9.             {
    10.                 return true;
    11.             }
    12.             if (filterA.GroupIndex < 0 && filterA.GroupIndex == filterB.GroupIndex)
    13.             {
    14.                 return false;
    15.             }
    16.             return
    17.                 (filterA.BelongsTo & filterB.CollidesWith) != 0 &&
    18.                 (filterB.BelongsTo & filterA.CollidesWith) != 0;
    19.         }
    20.  
    That seems straight forward enough but I was concerned about the cost of filtering. A boat can be intersecting multiple terrain colliders. Although likely not intersecting too many at a time. And the terrain colliders are low resolution (8-12m) quads.