The levels in Momentum are composed of dozens of smaller pieces, each with their own collider. Most do not require a kinematic rigidbody on them because with the method of control the player has, they’re rotated around the ball, meaning that there’s effectively no movement relative to the ball.
However, some pieces move on a predetermined path in the local space of the level, and therefore do require a kinematic rigidbody to handle the interframe collision stuff.
Moving an object with a large number of rigidbodies parented to it causes a large amount of lag, even if those rigidbodies are kinematic or disabled.
My solution was to have rigidbodies only on dynamic objects within some range of the ball.
Every few frames, we scan for colliders. This list is culled of triggers, duplicates, and static objects. Objects that pass all tests are removed from the level hierarchy, their transform information is noted, and a rigidbody is added to them.
Then every frame, these objects are moved by the script according to their position in the level hierarchy. (which is always notably below a mover. (Or else it would be static and would be culled))
these objects can later be removed from the list and added back into the level hierarchy during a later scan step if they don’t pass a distance test.
Again, since WordPress’ code formatting is terrible, here’s the code in question.