Optimizing thousands of game objects

Hi there,
Since I have started to develop my game, it went well, but now performance is my greatest enemy.
Game is 2D top down space game. I can generate systems (everything in one scene) but the problem is how to not get 30fps with 500+ ships ?

Some trade, some fight, some just roam around. I don`t want to just disable them, because that would completely stop the economy in those systems.

I was planning on either:

  1. Enabling the ship objects if they are closer the player than certain Distance.
  2. Disabling entire systems in player is currently not in it(Would kill off economy)

I`m not running any OnGUI on those ships, but ofc they have to have Update.
Also some ships have 1 or more turrets on it, which are also having Update, firing and instantiating bullets(which drains A lot of fps when I tried 500 ship battle)

Any ideas / optimization tips?

I worked on a game with a similar problem. Everything in the game world is constantly changing regardless of the player. What I decided to do (although didn’t get around to implementing yet) was create a “quantum world” system. Basically anything far away from the character would be turned off. Then, when the player moves close enough to an area, everything in that area would get turned on and would be randomly adjusted to simulate that time had passed and things had changed. Basically, it approximated how that area might’ve changed since the player had last visited. It would calculate the probability of different changes based on the general stats of those things (ex: this level 100 has a ~90% chance to have killed this level 10). The degree of randomness (or adjustment iteration count) would increase with the amount of time the player had spent away from that area.

In the end, the player experience should feel the exact same as if everything in the world was doing it’s own thing regardless of the player’s presence.

EDIT: And another thing, look up object pooling. Instantiation and destruction is costly. If you’re going to spawn a lot of the same object often (example, bullets), you should instantiate as much as you’d think you might need once at the beginning, disable them, and put them in an “object pool” (a referable list somewhere). Then when something needs a bullet, pull one out of the pool and enable it. When it’s destroyed, disable it and put it back in the pool again. The downside to this is that your game will be constantly using more ram, but it’ll probably be worth it.

And i’m not sure if Unity’s collision detection already uses broad phase checks or not, but it doesn’t look that up and implement that too. It’ll cut down a lot of unnecessary collision checks which can be very costly.

My thought is that you need to have two combat systems. One is your main system like you have now, but the other is a very simple system that runs when the player is out of range. You do not need ships that your player can´t see firing twice per second. Just do some quick math and group it together into like 15 second intervals.

The other thing is to use RNG to your advantage. If you tell the player there is RNG involved in combat, then you don´t have to be nearly as precise when doing your calculations. This is especially true in your economy simulator. Throw a little ´fake´ RNG into your equations, which will allow you to use less frequent updates and still give the player what he is expecting.

How about doing this?

//Do this every 10 seconds
for( int i=0 ; i<shipDatabase.Length ; i++ )
    if( shipDatabase!=null )
        Vector2 distance = shipDatabase.transform.position - playerShip.transform.position;
        shipDatabase.setActive( distance.sqrMagnitude<5000 );

Do you think it would work if shipDatabase array has 500+ objects?

i think that you can do everything in calculations and realize them only in the field of view