- Home /
Moving many 2D triggers is slow. Why?
Hi, I've got a scene with about 1600 2D colliders set as triggers and a rigidbody that is disabled. The problem is: when I move all triggers at once, it takes too much time on the main thread.
To clarify, actually moving the responsible GameObjects (changing transforms) takes about 13 ms when profiled. But at the same time, the movement is noticeably sluggish and the basic Game View Stats report around 120 ms. So clearly there's something going on behind the scenes. I strongly suspect Physics2D is the culprit here, because when I disable half of my triggers, the performance improves rapidly (to 40 - 50 ms).
Is there any way to bypass these extraneous physics computations? I really need only trigger detection.
Try to make sure the colliders are primitive shapes. Edge/Polygon colliders are more expensive. Other than that, nothing without disabling some colliders comes to $$anonymous$$d.
Do you really need to move 1000+ triggers in one frame? There might be a more lightweight means of achieving a similar effect. You might disable some of those colliders when they're not being used. You might distribute the move over several frames. You might write up some math that reduces the check complexity.
Also, are you seeing any messages in your console window? Either warnings/errors, or even messages you log out yourself. Some messages might indicate problems (like moving static objects), but another consideration is that each message takes several milliseconds to print.
@contab009 All shapes are either rectangles or circles. Vast majority are circles.
@rutter The thing is nothing I do in the code is just so expensive. I took a good deal of time to check everything. It's what happens on the Unity side that causes the overhead. I guess rearranging some sorting queues and maybe some preli$$anonymous$$ary physics computations I'm not aware of. So I don't know how would simplifying math on my side help short of re-writing the whole trigger subsystem myself. Also, there are no warnings or errors and objects are not static (I checked).
One thing you're both right about. I could disable most of the colliders before moving en masse and re-enable them afterwards. It will probably cause some delays at start and finish, but they'll probably be acceptable. Thanks for the idea. It's kind of obvious, but I guess I needed to hear it from someone else.
If the triggers have a rigidbody2d set as kinematic, does it make any difference?
@screenname_taken There's no rigidbody involved. It's disabled during the operations and yes, it's set as kinematic.
Anyway, I disabled all unnecessary colliders during movement and it works like magic! Thanks everyone for input!
Answer by Simon Says · Sep 13, 2014 at 08:06 PM
All right, I didn't manage to figure out the exact cause behind all this. But even if I did, most probably I couldn't have done anything about it. It's hardwired in Unity.
The bottom line is: don't move so many primitive 2D shapes at once as a part of continuous interaction or even real-time updates. Unity cannot handle it smoothly. My experiments show that about 500 simple triggers are barely manageable on a modern PC, giving close to 30 FPS.
My solution was to disable as many colliders as possible before performing the movement. It might not work for everyone. You might want to distribute movement across several frames as @rutter proposed, or simulate rapid movement of many objects in your script data and then apply it less frequently. Other than that there aren't many options but to write your own trigger management system, bypassing Physics2D.
This was experienced in Unity 4.5.2 and 4.5.4.