Performance issues with trigger colliders and lots of projectiles.

I’ve been puzzling over spatial awareness for units and building and ran into some performance issues before. So I setup a test of my own to see the performance with a few dozen colldiers with a ton of projectiles flying in any out of them.

alt text

alt text

As you can see the FPS drops pretty fast. I have 128 colliders here with no scripts attached to them. This seems like a reasonable amount of units that could all be within close range of each other in an RTS. If you had two groups of units of that size get close enough and start shooting at each other you could probably expect something similar to what I simulated here.

How do I go about increasing the performance of the colliders, while using them as triggers? There are obviously tons of projectiles that I really don’t care about, and that the units don’t need to care about. Yet they will trigger on entering the sphere colliders anyways, absolutely destroying my framerate.


I was considering space partitioning with an octree or something similar so units can tell what is close to them, and then just raycasting or something similar. It seems way over the top to me, however if that’s the appropriate solution for spatial awareness for a large number of units/projectiles I’ll go that way. I just want a few of you to weigh in on the problem first, before I invest the time and money in learning materials.


Edit: If you make the colliders into one large sphere so the projectiles are not entering/exiting multiple colliders along their path the performance is still terrible. Just having projectiles flying around inside of a trigger collider results in very low performance.

Scene download: MEGA

New Screenshot of using very large trigger colliders instead of smaller ones:
alt text

Don’t rely on Unity Physics to handle EVERYTHING in the world at once. it will teach you bad habits in game development, and your game will only run on high end computers.
I personally develop on a low spec computer to force myself into using optimized habits, but I can’t say I’m a guru in game optimization.

This is my recommendation.

Even the simplest sphere collider can become really slow if 128 objects have to check against all the other 128.
You end up with 128 * 128 checks EVERY fixed update…(and fixed updates are for the physics engine and are calculated multiple times for each frame)

There are tricks to RTS physics for large volumes, that saves on processing.
To keep in mind… only check for collision when it is relevant.

Units don’t need to crash into each other or bounce around right?
Or maybe they do in which case you should selectively enable and disable colliders…
If your units wil never ready crash, then you can make them avoid each other with you own distance checks and zone partioning as mentioned above?
A unit only needs to check against other units in the same or neighbouring zones.

For projectiles it’s not that simple as a projectile might travel across many zones…
If you aren’t worried(don’t care) about whether something can interfere with the projectile mid flight…
Then remove the colliders…(they’re not accurate at high speeds anyway)
Then you can plot the projectile’s trajectory to the destination before hand, and figure out where it is going to hit (so just ONE check per shot to establish destination)
Then you animate the projectile along that trajectory…
Then at the end of the flight you check to see if any colliders are there with a single sphere check inside your script. (just one more check per projectile at the end of it’s life)

(There are many variation on these ideas… But) Doing this will result in a huge reduction of physics processing.

In Summary, a unit only focusses on the surroundings, or you predict for projectiles and check once at the end…

(Converted Answer from two Comments, so this Question finally gets marked as Answered :wink: )

First thing to check:

Is it possible to use LayerCollisionMatrix (Physics Manager) with this specific Setup.

LayerCollisionMatrix allows you to to change the logic on how and which Layers interact with each other during Physics. This can improve the performance by a huge margin.

Specific to your Scene:

Okay I checked it and got it running at 70fps… But I’ll start at the very beginning.

In your setup, the Projectile kinda produce an heavy impact on the OnTriggerStay. Funny enough, OnTriggerEnterExit doesn’t even eat up 1/100 of what OnTriggerStay needs.

But that makes sense… Because OnTriggerStay gets called every fixedUpdate. So the larger the Area of the Trigger, the worse the performance.

To avoid that problem I adjusted your test Scene to a more Gameworld like setup with Colliders spaced further apart and in two rows, with the bullets flying in the middle (like they fly down a pathway or so).
I also reduced the Guns by half.

In this scenario, (keeping shift hold) my scene keeps at 70fps. And I still doubt you will get to such an extreme use of Bullets meeting Triggers in a game. 600 Bullets crossing a 120 Triggers at the same time?

About your main question how to optimize it without changing your setup:

I think you shouldn’t use Triggers on every unit, etc. Instead you could maybe use just one Trigger on a parent Object with 120 Units attached to it and then handle Events if the parent Objects interact with each other.

But you won’t be able to get around the problem, that calling OnTriggerStay about a thousand time per FixedUpdate will cause terrible framerates.

The only way is to use other approaches. :slight_smile:

alt text

Regards Michael