- Home /
Collision Performance Question
I can't seem to find many details about how collision detection in Unity works under the hood in the official documentation or from Google, so I figured I'd ask here. Do methods like OnCollisionEnter() behave more like the Update() function where the engine checks for a collision after so many frames, or does it behave in a more "event-based" way so calculations are only performed after two colliders overlap?
The point behind this question is I'm designing a game with a player that collects a variety of different pickups by colliding with them, so I'm faced with the following two options:
Have all collision detection handled by the player since nothing else interacts with these pickups.
Handle collision detection in the individual pickup scripts to determine what happens when the player comes in contact with them.
The first option obviously is much better performance-wise if OnCollisionEnter() behaves similarly to Update() since it eliminates multiple objects all trying to check the same thing every couple of frames. But the second option has the benefit of creating a more modular approach where there is a clearer separation of the actions being performed.
Answer by JVene · Nov 10, 2018 at 01:46 AM
The physics engine used in Unity is PhysX. The exact version depends on what version of Unity you use, but probably 3.2, or at least 3.2 documentation is largely applicable. Be aware, however, that while you can gain a great deal of detailed information by searching for PhysX information, the functions Unity exposes are named by Unity, and so you won't find exact matches for function names, nor is the entire physics engine exposed by Unity (though most of it is).
That said, collision detection is quite a science. PhysX uses a lot of optimization techniques. The cycle of the physics engine is associated with the Fixedupdate function, not the update function, and happens at a fixed time interval you can configure. Since you don't give volumes, I would offer only that if a single object is being tested for collisions against about 50 objectives, performance will be quite good, and the engine is designed to handle such volumes.
That said, if you're up to it, making your own detection system might be faster, but not necessarily by much. This is, in part, because what you write will run in C#, while PhysX is written in C++. Your primary advantage is that you can greatly simplify the detection, as in not creating a full fledged collision system, but merely a search method which determines if your player is in contact with a target. You would do well to mimic the broadphase of the physics engine, which makes "quick rejection" decisions by the simplest and fastest math (as in, if the x of the player's 'pointer' position is out of range, reject - then if the y of the player's pointer is out of range, reject - otherwise, test the player's pointer as a candidate selection, probably by distance (or distance squared)). Your challenge will be to efficiently create a database of the pieces to be searched which itself isn't the major performance burden (C# isn't nearly as fast at storage than C++).
For what you describe it is doubtful you'd have a performance oriented concern. PhysX (and thus Unity) is well designed for performance of the collision system. However, you may have extreme efficiency concerns targeting modest mobile hardware or some other reason to choose something that is processor efficient. Any solution you implement in C# is going to consume as much or more memory than the physics system, so if you don't use any physics in your game, implementing your own solution is going to be a better logical choice than if your game pieces also use physics (in which case you'd be creating, essentially, a duplicate/parallel system). It will be worth experimenting to get a "feel" for this sort of thing.
Very informative, thanks! I'll be sure to look more into PhysX. In the meantime, I think I'll just stick to limiting the number of OnCollisionEnter() methods I implement by letting the player handle collisions with pickups, since my understanding is that this function would be perfor$$anonymous$$g some calculations each time they collide with something else regardless of whether they are actually supposed to do anything or not.
Yes, under the hood, PhysX will calculate and therefore process every potential collision in the configuration (they can be limited to layers, for example). However, OnCollisionEnter (and the related functions) are merely responders, which is to say PhysX will call such a responder on every collision, obviating the call if such an override isn't in the user class (so the workload is still performed whether OnCollision... is used or not - only the call itself is 'saved' when you don't provide them).
Answer by thunderbuns · Nov 10, 2018 at 01:39 AM
I don't know exactly how OnCollisionEnter works. However, I would recommend having the collision detection take place in the player, rather than on each individual item.
Yeah, that seems to make the most sense to me too from a performance standpoint even if it doesn't make a huge difference with the amount of pickups generated at a time. Thanks for taking the time to answer!
Your answer
Follow this Question
Related Questions
Collision Killing CPU/FPS/Performance - Suggestions?! 0 Answers
Make a sprite stop after a collision. 1 Answer
my thing keeps going through walls, but ridged bodies can touch the collider 0 Answers
Inconsistent Particle Collision detection 0 Answers
Multiple Colliders On A Single Object Detecting Each Collider In OnTriggerEnter() 1 Answer