Advice On Reducing/Eliminating Colliders on Unity Project

hey Physics folks, first time posting in this particular forum so be gentle…

i have a music app i’m creating in Unity involving a rotating cube of 8 x 8 X 8 (8 independent layers of 8 X 8 grid sequencer). here’s a link to a demo on Youtube:

so, the current protoype uses colliders for each cell in the cube (512 in total).

2930315--216676--all Layers-pic02.png

there is a ‘playhead’ containing an object with a rigidbody for each row in a layer, so 8 playheads per layer for a total of 64 rigidbodies per cube.

2930315--216675--singleLayer-pic01.png

each layer is edited separately at the home position with the renderer turned on for a particular cell if it is active. the playhead then starts and on each cell there is a script detecting if it gets a TriggerEnter from the rigidbody in each row at its position. if the renderer on the detected cell is active the sound engine triggers the note for that row. there is also a layer collider used to detect the new position of cells after each rotation and to color them appropriately.

while 512 colliders and 64 rigidbodies isn’t a lot of overhead, this is a prototype. i want the final version to be 16X16X16 and also to run on a Samsung S7 with Gear VR. so if you do the math, that means 4096 colliders (512 X 8) and 512 rigidbodies (64 X 8). just setting that up in Unity Editor made it stagger quite a bit, so that makes me think that i need a much more efficient triggering scheme involving as few constant physics objects as possible. i’ve read you can use raycasts to determine hit points on a collider, but not sure how exactly it could be implemented.

anybody have any clues as to how to limit each layer’s functionality to as few physics elements as possible? any help appreciated!

First, profile what’s taking the time! Is it moving the colliders? Are the colliders you’re moving all attached to a single Kinematic body that you rotate? What exactly collides with these triggers, it’s not obviously from the video or the explanation. Could those (BoxColliders?) be replaced with SphereColliders as they’d be faster?

The whole set-up of a cube with regularly spaced colliders all with (seemingly) the same box shape could be replaced with a simple mathematical representation i.e. roll your own simple physics. Again, without understanding what collider with what, it’s hard to tell how difficult that would be.

A volume in space is easy to represent mathematically. If this thing acts like a Rubics cube with ‘layers’ rotating then it’s still easy as you only have a rotation to deal with for that ‘slice’. If you wanted to know (say) if a small sphere intersects a cell within that rotated ‘layer’ then you simply inverse transform the sphere so that it lives in the local space of the rotated ‘layer’. Checking if it’s within the whole bounds of the layer should then be easy then you can check which cell. Again, I don’t understand what collides with what so this is an example only.

well speaking about the functionality of a single layer only, i have 8 game objects parented to what i call a Playhead. the playhead has a Box collider trigger on it, and each playhead object for each horizontal row has a rigidbody set to kinematic, and a box collider trigger as well. in addition the layer has a layer detector in the form of a box collider trigger with a rigidbody also set to kinematic. all rigidbodies are frozen, however. so if you duplicate this layer functionality in Z depth axis you have 8 layers. that’s the triggering portion and it always stays in the same position/orientation(the playhead moves from left to right on each layer however) regardless of the rotation of the cube made of spheres. it’s just barely visible in the video. there is variation in length of sequence for each layer as well as rhythmic division so the layers intentionally can fall out of sync.

now for the cube - or as i call it, the Constellation - which is visible. currently the whole cube rotates in 90 degree increments, and consists of 64 cells per layer, for a total of 512 cells. each cell has a Sphere Collider set to a trigger and a script that detects when the playhead enters it with a standard OnTriggerEnter. so at full 90 completed rotations the music is synced properly, but at the tweening stage it falls in non-standard places relative to the playhead position, leading to the more chaotic moments you hear.

as far as profiling, i haven’t done much - or much that i could understand, anyway. i’m not an advanced programmer on this. but when i tried to duplicate the Constellation so there were 8 of them, the Editor slowed way down. removing the Sphere Colliders from the cells (4096 colliders) brought the Editor performance back in line, however.

i’m not sure about how you can do detection by not using physics components, but are you essentially measuring transform distances in that case? like maybe you take the transform of a playhead and when distance is less than some threshold to nearest cell you can assume it is in fact on the cell? hmm. makes me think of some options…

All I’m really saying is that perhaps using Rigidbody physics when you don’t need such physics is overkill. In the end, it sounds like you just want the convenience of collision detection only however maintaining a lot of colliders has an overhead. The overhead in your case might be the way it’s set-up or what your scripts are doing and only the profiler will tell you where your time is actually going; something a video or description here can’t tell me.

Yes, if you’ve got a fairly regular-space set-up of colliders then it might be easier to perform your own collision detection and remove any (potential) overhead you’re seeing from the physics system. For instance, a regular grid composed of adjacent boxes doesn’t really need a BoxCollider2D at each point, it could be stored in a simple array and ‘collision detection’ might simply be checking an array for occupancy. Note saying this is what you can do, just an example.

thanks a lot for the transform suggestion! i think i can do the entire thing without using physics components of any kind. because the playheads always move left to right and every layer is independent, i only need to check at each sequence step where the playhead is relative to an active cell, and when they are at the same X location the note fires. it really is that simple and i wasn’t seeing it. so your thinking really helped me break through. appreciate it!

1 Like

Sounds perfect.