Unity 2D Physics Collisions are slowing down my game.... a lot

So I am making a projectile hell mini rpg game right now. I am completely done with gameplay and most of the game. Just now, I tried to stress test my game a bit and it turns out that 150 projectiles colliding with something at any given moment will slow down my game down to 10 frames. This is unacceptable for a bullet hell game. It is not the projectile script itself but the actual collision that is hogging performance. However, 100 projectiles colliding at once will keep my frame rate at slightly above 60 fps. Here is my projectile prefab:
2210830--147028--component.PNG
I’m very scared right now because I am going to start to create a trailer for greenlight and I need to show off how extreme this game can get.

Some more information about the projectile script: It lasts only a few seconds depending on range and I am using transform.Translate to move the object. Do you guys have any idea how to optimize any further??

These are just guesses but I’m assuming you are removing objects just after they leave the screen so it probably isn’t cleanup. Would it make a difference if instead of having the trigger on each bullet you have the trigger on whatever is being hit?

Yes I pool the objects. Also, I’m not sure that would work because the projectile spawns at the enemy position. On top of that, enemies would take damage from each other. To prevent this, I have to make a get component call every time an enemy touches a projectile just to check if the projectile is directed towards them or not. Do you have any ideas on how to efficiently decide if a projectile is directed to the enemy or not?

Also, each bullet carries damage information. I don’t want to use a costly get component call just to get that information. Any ideas?

Not really, I’ve seen your answers to other posts so know you know way more than me. Could you use that setting in the physics manager (Edit->Project Settings->Physics) to get it to ignore collisions between whatever shouldn’t react to each other? It’s in the Layer Collision Matrix. It might be quicker than checking the code on each bullet to see what it has hit & if it should do anything.

1 Like

Good idea. This should solve the wrong enemy collisions. And to avoid the GetComponent calls, I will make a static function in the projectile script that will set a local variable a damage amount. I will do the same thing for grabbing the damage amount.

I will do this in the morning its 2:30 am here haha. Will let you know how the performance is

Steps

  • Check the profiler. Post it here.
  • Disable collisions between bullets. And anything else with layer based collision
  • Check the profiler
  • Optimise wherever you are constrained
  • Check the profiler

It’s also worth mentioning the profiler is really useful in these situations.

2 Likes

Yes I checked the profiler and it says that my collisions are taking 76% of my cpu performance. I will post a pic in a minute

2210942--147037--Capture.PNG

1 Like

I’ve wondered if for a game with loads of bullets it would be best to use particles for the bullets, IIRC they only work with 3D physics though, should be able to support more then enough though!

2 Likes

Does messing with the collision matrix help? I’m picking most collision checks will be between bullets. But bullets don’t need to collide with each other.

1 Like

I’m kinda jumping in at the end here, but have you tried doing a ray between frames instead? That sometimes works better for bullets and avoids telescoping.

1 Like

moving static colliders?

Not supposed to be a problem anymore from 5.0 on. But it’s still worth checking.

There are clearly a lot of things going on here that might need checking:

  • BaseAI is eating 88k memory in this frame, if that’s par for the course, that’s pretty intense.
  • Collider cleanup is using 22% of the process, so something is clearly a little funky.
  • GameObject.deactivate is being called 57 times in this frame (if that’s normal, again, that’s pretty intense) it’s also taking a massive 17ms.

If on average you’re like activating and deactivating 57 game objects per frame… that’s just sort of crazy.

Just looked at the profiler again, 25,000 contact points is a big deal too. And if I’m reading it right there are over 3000 colliders in the scene. That’s a lot for any engine to handle.

That’s gonna be a seriously extreme trailer.

Edit: it’s actually firing trigger enter 3000 times that frame… so if it’s only 3k colliders, all of them are touching. This is probably why the transform change is so expensive. My guess is that you have something like 178 colliders overlapping one or more other colliders this frame, which is generating a total of 3000 collisions this frame.

I just re-read ops post. This is his design as stated initially. The stated problem is that when you have 178 collisions in a single frame there’s a performance problem…

Unless they didn’t update the docs (totally possible), you still want rigidbodies. Considering most of what the profiler says seems to be moving the collider, that could very well be it.

Unfortunately no. Bullets no longer collide with each other. In fact, I made it so they cant collide with anything and Im getting the same results. Only when I disable the circle collider could I get a good frame rate.

Hmm I just checked this out and it turns out it’s because I make a GetComponent call in order to update the damage on the projectile it just fired.

Yes this is pretty bad however this might be necessary to pool the objects. Maybe Im doing something wrong but I doubt it because I’ve looked over the code and it is as efficient as I could make it.

Definitely not :slight_smile:

That’s really weird. There’s only about 200 projectiles, each with one collider on it. On top of that, there are 63 enemies shooting projectiles and one player.

lol

EDIT: YOOOOO I just realized that the projectiles don’t even have rigidbodies. That means they can’t collide with each other anyways. In fact, it was the enemies colliding with the bullets and each other that really made the performance hit. Let me show you the updated profiler:
2211444--147074--Capture.PNG
As you could see, there is still large spikes every other second for some reason. My game however runs at over 60 fps for one or two seconds then drops to 10 fps at random intervals. What else could I do to optimize?

Looking further into it, it is definitely the enemies colliding with each other. I have made sure their layers don’t collide but for some reason they are still registering with each other. That is strange. If somehow I can make them not collide with each other, I should be able to keep my game at above 60 fps.

Its not the number of collisions per se, the biggest time chunk is in Physics2D.Simulate. I’m thinking the particle effect or ray casting solutions suggested earlier might be better. That way you can remove the colliders and ridgidbodies off of your bullets.

In unity 4.X moving colliders had to have ridgidbodies for acceptable performance. It was supposed to be fixed in 5.X. But its still worth a try. If it moves try putting a ridgidbody on it and see if that helps.

This was done for the 3D Physics (with the Physx 3.3.1 upgrade). Was the same was done for Physics2D?

Oh I would really hate to replace everything with 3d colliders. That will be my last resort though. Im going to try to raycast and see how that goes. The only downside to that is that I have to make a OnTriggerEnter equivalent so that the enemies don’t get damaged twice by the same projectile.

Also, I added rigidbodies to the projectile but I still have a performance problem.