- Home /
What's the best way of handling hundreds of objects in an infinite world without killing the framerate?
So, I have an infinite level generator set up.
It basically instantiates tiles (floor + some models on it).
My render/shadow/AO distance is already at around 60, so GPU load is no big problem.
However, it seems having a high amount of objects in general can cause the framerate to go down (noticed that after flying through my world for a while).
All distant objects are still active (because I'm not sure if disabling them might require more performance than leaving them active), they don't have scripts, but they do affect framerate as the world gets bigger.
Should I apply LOD to every single object? Does culling even affect CPU performance since it's outside of the clipping plane anyway? Should I disable the meshes when they are far away using triggers?
Thanks in advance.
Is your level generator deter$$anonymous$$istic? If so, you can destroy the distant parts of the world as they are not needed, and just re-generate them if you come back.
If your level generator is not deter$$anonymous$$istic, or the world may otherwise change in unpredictable ways (e.g. player construction and $$anonymous$$ing), then you can try saving the distant portions of the world to disk and deleting them, and loading them from disk when needed.
Well, currently the world is static, but a "non-euclidean" level would actually be a nice twist.
So yeah, that's an option, but how CPU heavy is destroying? In my case, around 5-10 tiles each containing 5-10 meshes would get destroyed in one frame, I hope that doesn't result in a spike.
Also, how would it detect the distance? I guess the most efficient way would be a trigger, and when the player leaves the trigger it gets destroyed.
EDIT: Frametime spikes are my main concern, RA$$anonymous$$ is no problem. The player would need to spend days walking around to even hit 500 $$anonymous$$B.
What do you think?
There is no need to destroy everything all at once, spread it out over time. If you 100 world pieces that suddenly become a candidate for deletion, add them to a list and destroy them only a few at a time.
There would be many ways to get the distance. You can use trigger zones, but be careful when setting this up - having many overlapping trigger zones that are configured to trigger each other (e.g. by being on the same layer) can cripple performance very easily.
You can also do a simple distance check to the camera. You can set this up similarly to how the above destroy works, only checking a small number per-frame to keep performance good regardless of the number of objects.
Are all your tiles seperate gameobjects? If yes, then that's very bad. Use chunks ins$$anonymous$$d and combine tiles into one mesh per chunk, and make each chunk as large as the vertex limit allows.
They are separate GOs indeed...
I'll look into combining as much as possible.
I don't know if I can combine the props (every tile has a random set of props) but at the very least I can make the floor huge and not per-tile.
Answer by joelybahh · Sep 11, 2017 at 11:42 AM
@N00MKRAD Disabling them will most likely benefit frame rate from my experience. also using LODS for all your procedural content will help drastically!
Occlusion Culling will definitely help! however, that may require some custom code on your front because unity by default simply bakes in the culling, so any procedural landscape will require your own implementation!
And yes! I have run tests before and culling does do wonders on performance, especially in dense areas of shrubbery.
A simple method could be to simply use the Vector3.Distance, and set a distance threshold that when exceeded, disables the distant object if(Vector3.Distance(player.position, terrainChunk.position) > DistThreshold) terrainChunk.SetActive(false);
however better methods are no doubt floating around google!
I hope I have helped you out a little, but long story short, yes disabling the objects far away will definitely benefit performance in a good way! if you need any more help feel free to reply :)
Well, keep in $$anonymous$$d that they are not rendered anyway. Does disabling (Or Occlusion Culling or LOD) still help, even if they are behind the cam's clipping plane?
I mean, they aren't rendered anyway.
And isn't it kinda expensive to calculate the distance to the player on thousands of objects?