Runtime creation of CustomPhysicsSystemGroup

I’m porting my previous, customized GroupIndex / Tag based multi-world to the new Entities 1.0 physics worlds, but it seems the split into worlds happens… at compile time?

How can I instantiate and register a new CustomPhysicsSystemGroup at runtime?

Or is there another way? I need to differentiate between around 100 physics worlds, as the minimum. Most are very sparse, often with all bodies at sleep.

Some need to be created on the fly; I can work out a pooling / index assignment system but I wonder what some good approaches would be, other than creating a file with 100 descentants of CustomPhysicsSystemGroup to get this going.

Edit: The challenge appears to be the baffling behaviour of AddSystemManaged to disallow multiple additions of the same system. I can also not construct different instances because CreateSystem does not allow parameters to be passed into the constructor.
8709714--1176843--upload_2023-1-6_13-39-13.png

Following Unity tradition of selectively making random fields likely relevant for typical extension cases inaccessibe to implementors, of course CustomPhysicsSystemGroupBase.m_WorldIndex is private even though it would be perfectly fine to write to it during a descendant class object’s construction.

8709714--1176846--upload_2023-1-6_13-41-36.png

I don’t completely understand the usage here, but it sounds to me like you want to process groups of entities together, grouped by a particular index value. This is a perfect job for shared components; you would make a query or a job for a particular value of a shared component that represented which physics world you were talking about, and do that separately for each value. Shared components also make sure that entities with distinct values of a given shared component are grouped into separate chunks, which seems convenient for this.

(Moreover, if you’re using Unity.Physics, this is already how entities are grouped into particular worlds, via the PhysicsWorldIndex shared component.)

Does that sound promising?

In general, having per-instance data on a system instance itself is not recommended, nor is having multiple instances of the same system in a single world, which is why we changed the API this way. The happy path is to have one of each system, which processes ALLL the relevant data in a given world in one shot. This reduces system overhead, too, and works better with ISystem, which can also be bursted.

Yup, this is exactly what I am trying to achive!

According to the docs, I need to manually instantiate my own Physics systems for each PhysicsWorldIndex beyond index zero I wish to simulate.

The only way I have found to do this is via AddSystemManaged, with T being a CustomPhysicsSystemGroup inheritor. This unfortunately doesn’t allow you to use a class more than once, and due it to being a genreric, it’s not trivially obvious how to create these CustomPhysicsSystemGroup inheritors programmatically.

I cannot do this, for instance:

            for (uint i = 1; i < 100; i++)
            {
                World.DefaultGameObjectInjectionWorld.AddSystemManaged(new CustomPhysicsSystemGroup(i));
            }

(this does not compile because the constructor of CPSG is protected)

nor can I do this:

            for (uint i = 1; i < 100; i++)
            {
                World.DefaultGameObjectInjectionWorld.AddSystemManaged(new MyCPSG(i));
            }

(this fails at runtime, because AddSystemManaged will reject any system type that has an instance already added)

Before I delve deep into reflection to create the types at runtime, or to spend days reading up on Roslyn and how that plays with Burst, I wanted to ask here if I am seeing things incorrectly.

To elaborate on my use case:
I have a floating origin space system that partitions the world into physics “bubbles”, each with their (local) origin. Examples: The surface of a moon, or the vicinity of a space station, or a debris field in deep space, etc.

On any entities not in the current bubble (indeed! perfect use case for a SharedComponent filter) the player interacts with, I add “DisableRendering”, therefore they are still simulated, just invisible. I merely arrange my camera stack accordingly to make it look like the player is somewhere millions of miles away; and it works like a charm.

There are a couple hundred of these worlds (up to a thousand, but most of them rather sparse or completely static - it’s a space game, and one of the longer term goals would be to also tick update these distant worlds a bit less frequently, if ever necessary). Either way, the hard minimum of PhysicsWorldIndices needed is around a hundred, the dream is maybe a thousand, or arbitrary creation and removal of these bubbles as needed.

What I had before entities 1.0:
I used to solve this with a hack to CollisionFilters prior to Entities 0.50: I changed the code so groupIndex requires equality for any collisions to take place, and then resolution is exactly the same as if groupIndex is 0.

Unfortunately these are not a IComponentData/ISharedComponentData, but instead, and incomprehensibly, a field inside the collider blobs (see below for other problems this causes), and I don’t feel running tens of thousands of “force unique” physics shapes is the right answer, but I don’t have a better one. I know this probably interferes with some of the BVHs, but I figured I could mitigate this by staggering the local origins so not every bubble has a mesh collidr right at 0,0,0.

Tangent: Other problems CollisionFilter as part of colliders causes is that it makes changing collision behaviour of entities rather tedious, e.g. a rocket being launched from a space ship no longer can temporarily change its CollisionFilter but needs to switch to an entirely different collider copy in order to “arm” itself after leaving the space it shares with the ship’s collider. I can’t be the only one who’s run into this one, maybe I am looking at it wrong?

I mean, surely this isn’t really the way multiple physics worlds / layers are intended to be declared and instantiated? Thanks btw, python! :stuck_out_tongue:

(this creates a large number of clashing sync points… this can’t be the way, each system takes longer than the single index 0 system currently holding ALL the objects with ease. it also makes PhysicsWorldSingleton pretty useless and thus works very poorly with raycasts, where formerly I would merely need to change my interaction - e.g. mouseover - to raycast using a different groupIndex)

I think I will go back to hacking collision filters unless you can maybe suggest a fundamentally alternative approach, I’m really curious. :slight_smile:

using Unity.Entities;
using Unity.Physics.Systems;

namespace Jovian.Systems
{
    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem1 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem1() : base(1, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem2 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem2() : base(2, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem3 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem3() : base(3, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem4 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem4() : base(4, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem5 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem5() : base(5, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem6 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem6() : base(6, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem7 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem7() : base(7, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem8 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem8() : base(8, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem9 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem9() : base(9, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem10 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem10() : base(10, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem11 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem11() : base(11, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem12 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem12() : base(12, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem13 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem13() : base(13, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem14 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem14() : base(14, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem15 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem15() : base(15, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem16 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem16() : base(16, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem17 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem17() : base(17, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem18 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem18() : base(18, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem19 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem19() : base(19, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem20 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem20() : base(20, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem21 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem21() : base(21, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem22 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem22() : base(22, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem23 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem23() : base(23, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem24 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem24() : base(24, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem25 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem25() : base(25, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem26 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem26() : base(26, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem27 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem27() : base(27, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem28 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem28() : base(28, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem29 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem29() : base(29, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem30 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem30() : base(30, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem31 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem31() : base(31, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem32 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem32() : base(32, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem33 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem33() : base(33, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem34 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem34() : base(34, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem35 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem35() : base(35, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem36 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem36() : base(36, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem37 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem37() : base(37, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem38 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem38() : base(38, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem39 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem39() : base(39, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem40 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem40() : base(40, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem41 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem41() : base(41, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem42 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem42() : base(42, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem43 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem43() : base(43, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem44 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem44() : base(44, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem45 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem45() : base(45, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem46 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem46() : base(46, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem47 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem47() : base(47, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem48 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem48() : base(48, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem49 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem49() : base(49, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem50 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem50() : base(50, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem51 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem51() : base(51, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem52 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem52() : base(52, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem53 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem53() : base(53, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem54 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem54() : base(54, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem55 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem55() : base(55, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem56 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem56() : base(56, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem57 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem57() : base(57, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem58 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem58() : base(58, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem59 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem59() : base(59, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem60 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem60() : base(60, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem61 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem61() : base(61, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem62 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem62() : base(62, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem63 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem63() : base(63, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem64 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem64() : base(64, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem65 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem65() : base(65, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem66 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem66() : base(66, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem67 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem67() : base(67, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem68 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem68() : base(68, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem69 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem69() : base(69, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem70 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem70() : base(70, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem71 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem71() : base(71, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem72 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem72() : base(72, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem73 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem73() : base(73, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem74 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem74() : base(74, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem75 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem75() : base(75, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem76 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem76() : base(76, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem77 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem77() : base(77, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem78 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem78() : base(78, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem79 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem79() : base(79, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem80 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem80() : base(80, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem81 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem81() : base(81, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem82 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem82() : base(82, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem83 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem83() : base(83, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem84 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem84() : base(84, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem85 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem85() : base(85, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem86 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem86() : base(86, false)
        {
        }
    }



    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem86 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem86() : base(86, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem87 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem87() : base(87, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem88 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem88() : base(88, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem89 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem89() : base(89, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem90 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem90() : base(90, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem91 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem91() : base(91, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem92 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem92() : base(92, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem93 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem93() : base(93, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem94 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem94() : base(94, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem95 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem95() : base(95, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem96 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem96() : base(96, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem97 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem97() : base(97, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem98 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem98() : base(98, false)
        {
        }
    }


    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class PhysicsBubbleSystem99 : CustomPhysicsSystemGroup
    {
        public PhysicsBubbleSystem99() : base(99, false)
        {
        }
    }

}

That is my old and current approach to multiple physics “worlds”, patching com.unity.physics.CollisionFilter. This works extremely well with raycasts, not so well with moving entities from one world to another (due to CF and groupIndices being baked into colliders, I can see how CF make sense, but groupindex really does not. they really ought to be IComponentData)

//Patched CollisionFilter by me
        public static bool IsCollisionEnabled(CollisionFilter filterA, CollisionFilter filterB)
        {
            if (filterA.GroupIndex >= 0 && filterA.GroupIndex == filterB.GroupIndex)
            {
                return
                    (filterA.BelongsTo & filterB.CollidesWith) != 0 &&
                    (filterB.BelongsTo & filterA.CollidesWith) != 0;
            }
            return false;
        }

original code was (I still strain to see any scenario where this original GroupIndex implementation can expect a good amount of use, it appears pretty far removed from actual situations I have encountered in game dev that weren’t already covered by Categories). I know this is the Box2D way of doing things, but I think that should be reconsidered.

//Original CollisionFilter for discussion
        public static bool IsCollisionEnabled(CollisionFilter filterA, CollisionFilter filterB)
        {
            if (filterA.GroupIndex > 0 && filterA.GroupIndex == filterB.GroupIndex)
            {
                return true;
            }
            if (filterA.GroupIndex < 0 && filterA.GroupIndex == filterB.GroupIndex)
            {
                return false;
            }
            return
                (filterA.BelongsTo & filterB.CollidesWith) != 0 &&
                (filterB.BelongsTo & filterA.CollidesWith) != 0;
        }

My approach has some issues with the BVH in Unity.Physics, which clobbers the IndexGroup to 0 because it creates so many collider unions and has no idea how to treat them (neither my scheme, nor Unity’s/Box2D’s own scheme).

In an ideal world, I’d find a way to reject collisions for IndexGroup 0 (which is “null” in my context), but I can live with it as-is for now.

I’m considering a system instead where I add a layer field in CollisionFilter and BVH creates some sort of separate tree per layer. Not sure, this is out of scope for me given how much of a moving target Entities 1.0 still appears to be.

Second hack idea might just be more bits; like a 128 bit int or so could constitute a working layer which those BVH unions could play well with. Seems wasteful, especially in light of the ridiculous requirement of unique colliders.

Third alternative I want to try would be to encode the world index in the top 8-16 bits of the BelongsTo/CollidesWith masks, and hack the filter code accordingly. That bitmask would still get clobbered by the BVH build step (but not to zero, but to 11…1111), so at least there could be some optimizations to be gained. Possibly with a rolling bit pattern logic or something, IDK, out of scope right now.

Anyway - I had extremely high hopes for PhysicsWorldIndex, which promises to do all that without open heart surgery on Unity.Physics; but apparently that has too many limitations due to the problem described in OP, and the massive, inexplicable slowdowns experienced beyond ~30 systems, regardless how sparse, dormant, or empty the World is.


I mean… if it seems stupid, but it works, it’s not stupid, right? :smile: Getting acceptable physics performance with 10,000 such colliders with hacked GroupIndex matching.

Still would like Collision Filter or at least IndexGroup as a componentdata. (someone else made this request, I can only concur)

Thanks for sharing this Thygrrr. You have helped my understanding greatly. Would you mind sharing how you were able to resolve the issues with BVH setting the IndexGroups to 0? I am encountering the same issue as you it seems:

https://discussions.unity.com/t/bizarre-collisionfilter-failures-when-using-groupindex-bounces-clip-through-then-accelerates/1554297