- Home /
 
Question is off-topic or not relevant
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?
You could just switch off the renderers.
Look into batching and joining meshes, both being very good techniques to reduce draw calls and VBOs.
Renderers aren`t taking any FPS :) I tried to do those 500 ship battle, I selected every object in Hierarchy, turned of Sprite Renderes, and FPS didn`t drop a bit. It`s the amount of code it needs to perform I think.
If 500 turrets needs to instantiate 2 bullects a second, that is 1000 objects created every second. + for each loops for measuring distance between ships (however I run this only once 1.5s, though it has to still loop through all 500 objects in entire scene)
It could be many things that are causing this, do you have Unity Pro? If you do then use the profiler to find out what is causing your frame rate drop, without this you(and us) will just be guessing...
Don`t have Unity pro, and I already optimized it very well. It`s not that I have bad performance and don`t know what I`m doing :) I just read some developer of 2D game had 14 000 ships in scene with 40-50fps. If I cannot even get 1000 with C# - Unity3D, then don`t know where the problem is.
That`s why I`m asking here if you don`t have any tips for me :)
That's a lot of help.
Not one click of +1 to be found :/
Answer by Carve_Online · Nov 19, 2014 at 11:19 PM
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.
Answer by PsychoDuckArcade · Nov 20, 2014 at 12:12 AM
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.
Answer by Wrymnn · Nov 20, 2014 at 07:57 AM
How about doing this?
 //Do this every 10 seconds
 for(int i=0;i<shipDatabase.Length;i++)
 {
     if(shipDatabase[i] != null)
     {
          Vector2 distance = shipDatabase[i].transform.position - playerShip.transform.position;
          if(distance.sqrMagnitude > 5000)
             shipDatabase[i].setActive(false);
         else
             shipDatabase[i].setActive(true);
     }
 }
 
               Do you think it would work if shipDatabase array has 500+ objects?
What is that supposed to be? You are the poster why are you asking via answer...I close this question as it is not leading anywhere. Come up with a more precise problem.
There were several people helping me with my problem. I posted this "solution" for them. Because this would work so I could mark it as answered right away and close this thread myself. But also wanted to ask them if this would be the best of solutions.
This was what I told you to do, but you claim you needed the object to do things while far away. This is deactivating the object so it will not do anything. This is not the right answer.