How to optimize hundreds of sphere colliders


I realize that this is quite ambitious, but I should explain my reasoning why. The game I am creating spawns hundreds of friendly fighters ships, each of which have an enemy detector. This detector is basically an invisible sphere collider that “sees” if any enemy is too close; if so, it chases it.

Originally, friendly ships hit each others’ detector, causing performance issues. So I decided to make them ignore each others’ detectors by using layers and performance improved. I can make about 400 or so ships now before things really slow down. Without the enemy detector colliders performance is even better – but those detectors are necessary.

Any thoughts? I suppose I should probably use some kind of grid, kdtree, or data structure to somehow help performance, although I’m not sure where to start. I’m also not sure if unity’s internal engine helps in this regard.

Thank you

Do you have any rigid body on them? If you use any collider without a rigid body, and move them, physx will bake the static collision data causing performance hits. If you haven’t got rigid bodies on them, just slap them on and set isKinematic to true and you should see some improvement.

Another thing you could try is to perform a Physics.OverlapSphere every 0.1 seconds for detection purposes, but that would also require a collider on them.

Another bit of speculation is the scale of your objects. I don’t know in depth how this work but generally, if physx uses some octree and your objects are too small (all inside one bucket) then collision detection should be slow since it can’t efficiently cull away the majority of objects. This is just some thought I had, but I don’t know the scale of your game, neither do I know any optimal scale for the physics engine, if any applies.

Could you do away with the colliders altogether and just use Vector3.Distance.sqrMagnitude calls? In your Start() function, create a list of all the fighters using GameObject.FindGameObjectsWithTag and then iterate through this list? Possibly iterate through on a coroutine that batches the checks so that some subset gets checked every frame? I honestly don’t know if 400^2 simple float operations would be faster than 400 collider checks by the physics engine, but it would be relatively quick to try.