This thread has 3 sections, the nature of the problem, that things I’ve tried to fix it, and my suspicion as to what’s causing it. If you wish to help please read it all. The last thing I want is for someone to suggest object pooling, because they didn’t read that I tried that already.
The nature of the problem:
I am making a 2d shooter, if my tests look promising I may try and get serious about its development. However, when spawning lots of bullets at once, particularly if the bullets are spawned close or on top of each other, I suffer major frame rate dips.
The FPS dip occurs right before this moment, but it takes a quarter second for the stats to catch up, but as you can see, very low FPS when the bullets are spawned. See attached Image 1
But once the bullets spread out a bit, the FPS goes above 60, but there are the same amount of bullets on the scene, as you can see by the animator components on the bottom: See attached Image 2
I checked other Bullet Hell shooters like GunVein and Touhou, and they spawn bullets on top of each other all the time. They aren’t made in Unity, but I also double checked Bullet Hell Monday Final which was made in Unity, it does the same, spawning bullets in droves and yet it runs flawlessly.
That is the nature of the problem, but before I go on to my attempted solutions, here is a little more info on the bullets:
They do not use rigidbody2d components, they use a circular collider, which is a trigger, the player’s hitbox detects if it collided with an enemy bullets which is how the bullets damage the player. Here is the script that moves each bullet:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemybulletspeed : MonoBehaviour
{
private float speed; // Speed of the bullet
// Method to set the speed of the bullet
public void SetSpeed(float newSpeed) //the enemy ship that fires the bullet sets the speed of it
{
speed = newSpeed;
}
// Update is called once per frame
void Update()
{
// Move the bullet forward using its specific speed
transform.Translate(Vector2.right * speed * Time.deltaTime);
}
}
The solutions I tried:
Off screen bullet removal: Obviously I have already programmed the game to set any bullets that move off screen as inactive, which has a little buffer distance off camera. The bullets are not destroyed but are set as inactive because of my next solution
Object Pooling: Naturally, I have also setup an object pooler, during tests I can see how many bullets are in the hierarchy, it automatically instantiates bullets if the Pool for that bullet type is depleted, eventually hitting an equilibrium where it no longer needs to create new bullets. This hasn’t made a difference, when activating lots of bullets at once and seemingly on top of each other, I suffer frame rate dips each time these ships fire. Even after all the bullets would have been instantiated.
Collision layers: My next suspicion was that the bullets were colliding with each other. Although there is no code that triggers if an object that is tagged as “enemybullet” hits another object tagged as “enemybullet”. Only if it hits an object tagged as “player” or “terrain” does it actually do anything. Nevertheless I suspected that the game was still registering the collisions between “enemybullets” even if there was no code that triggers because of it. So I did some research and found that if you go into Edit>Project Settings, and from there go into Physics, I could prevent certain layers from interacting with each other, My bullets layers are 9, 10, 11. 9 for the larger bullets, 10 for medium sized and 9, for small bullets. Then I edited the layer collision matrix as follows: See attached Image 3
This should prevent Enemybullets from colliding with each other, and I tried making code to print a message in the console if an enemy bullet detects a collision with another enemy bullet, I never received that console message so I’m confident that the game isn’t registering collisions between all the enemy bullets that spawn on top of each other.
Spawn bullets not on top of each other: Well if the bullets are causing FPS dips when spawning on top of each other, I decided to make an offset so that the bullets spawn a bit like this:
See attached Image 4
That makes less bullets stack on each other, but it hasn’t helped, I still suffer frame rate dips. I double checked other bullet hells, I thought maybe that’s actually how they do it and I just never noticed, but no, their bullets very often spawn from a central point all in a huge stack.
Overcrowded layer?: My final attempt involved putting the bullets on separate layers, as you can see from the above screen shots, the outer most bullets travel a bit faster than the inner most bullets, because they are assigned a different speed when fired, but they spawned at the same time and on top of each other. So I suspected that the sprite renderer was having difficulty because all of these bullets were spawning on layer 10, so I made the faster bullets a part of layer 9, thinking that somehow… having too many bullets on layer 10 made Unity unsure of which bullets should be displayed first and that somehow affected the FPS
Sprite Atlas: I don’t know much about Sprite atlas, but I created one and added all of my bullet types to it so far. I have no idea if I did it right: See attached image 5
My final suspicion:
I still think that somehow, the issue is caused by sprites stacking on each other, why that causes problems, I don’t know. But to test, I tried spawning a bunch of ships, these guys are programed to follow the player to attempt a ram. I would upload more screenshots but I am limited to 5, just take my word that if they are spread out, even if I have 80-100 on screen, I suffer no FPS issues. But over time since they are all converging on a central point they eventually stack up, and causes horrendous FPS issues. Of course I would design the game so that these ramships won’t stack on top of each other to that degree, but I need the bullets to be able to do that.
That is my suspicion, I have no idea where to go from here. No optimization tutorial mentions anything like this, nothing for 2D games at least, I can’t find any forum here or on google that mentions an issue like this. Any help is greatly appreciated