9uile wrote:What is the maximum bullets to have an impact of the framerate?
In the video I posted above, I only have around 600-700 bullets on screen, but even at around 2,500 bullets, the project runs well above 60 FPS, even in the Unity editor.
9uile wrote: Do you have an active collider on each bullet ? I heard that it can reduce the perfs. Some people use a colliderless method.
I do not have a collider on the bullets. My EnemyBullet class is a simple class that doesn’t even inherit from MonoBehaviour. The only attributes it has are pos, vel, rotation, speed, and reference to animation data (more on that below).
I received a recommendation in another forum post here that Collider2Ds were blazing fast, especially if you have a RigidBody2D on the object with them, but I noticed performance issues when I started putting hundreds of bullets on screen. That said, it wasn’t just the physics causing issues. Even with an object pooling system where you activate and deactivate objects rather than instantiating and destroying them on demand, the activating and deactivating eats a bit of performance. Similarly, I found when using the profiler that Animator updates were eating up quite a bit of performance when there were hundreds of bullets on screen, all animated.
That brings me to your final question.
9uile wrote: Are your bullet sprites animated with a script or with the unity animator ? I wonder what is the best option for performances.
I found that using the native Unity animator functionally was not the best option for me. I discovered
this video on YouTube where Code Monkey uses the preview ECS package to render 100,000 animated sprites. I first tried following that method directly, converting my project to ECS, but ultimately I stalled out, so went back to normal Unity object oriented stuff. I nevertheless managed to port the method over and it works well.
Basically, rather than have a SpriteRenderer and Animator on a GameObject, I have another bare bones class called AnimationData that contains info like frameCount, frameDuration, currentFrame, uv, trs_matrix. Each bullet has a reference to an instance of this data.
The data itself is used by a BulletRenderer singleton script on a GameObject in my base scene, which has a reference to a single quad mesh and some simple materials which contain my bullet spritesheets. Each frame I update the bullet positions, I also update the anim data for each bullet (by altering the trs_matrix to make sure the draw follows the bullet and so on), along with checking to see if I need to advance the current frame. Then, in my BulletRenderer, I batch the AnimationData into chunks of 1000 and use Unity’s DrawMeshInstanced() to render them from the single mesh.