- Home /
How static batching works
Hi everyone,
I need to use the StaticBatchingUtility to batch all the static GameObjects in my scene. The GameObjects have to be dynamic at start (so I could access and change meshes), so I can't use unity's default batching.
The problem is that my scene is pretty big, and I have lots of GameObjects scattered around the scene. I can't just batch all the Objects with the same material to one mesh, because they might be far from each other and it is not effective.
As far as I understand, when unity does the static batching, the objects are batched in groups, and not in one big mesh. An I correct? If it's the case, is there a way to see those groups? So I will be able to save them and than use them in my own batching.
If not, what is the best way to perform the batching?
Many thanks, Anton
Answer by Statement · Dec 09, 2013 at 06:58 PM
Static batching bakes your models into one huge mesh. This means that if you had 1000 wall segments, all using the same model, then static batched them, you'd be using 1000x memory than using a single model. It would reduce draw calls on the expense of used memory. Put simply: It creates one huge mesh out of several instances of smaller meshes.
When you render something, a few pieces of information is required, like what model to render, what indices of that model should be rendered and what material to use.
Unity will try to render as many parts of your staticly batched mesh as possible, using a shared material. If there is no shared material, and if many parts use different materials, Unity is forced to render each collection (based on material) individually.
Even if it's one big mesh that is generated, not all of this is used to render it every frame. Unity will look at what renderers should be visible, and rebuilds an index buffer for your statically merged mesh. Put simply: Unity will exclude the vertices that belong to a renderer that is not visible when rendering the mesh, to avoid rendering things outside your frustum.
This process has some overhead of course since Unity has to rebuild indices every time a renderers leaves or enters the frustum. If you are using profilers you may see that it's using some time for batching. This is typically what happens for static batching.
Batching should be used with consideration. If you are already running dangerously low on memory, turning static batching on may crash your app. Try to use few unique materials for batching as it allows Unity to reduce the number of draw calls. If batching is slow, consider reducing the number of triangles per mesh or number of renderers in your scene.
Static batching generally dramatically improves render time but may increase memory footprint.
You can see the static mesh if you have a static object and select its mesh. You can also find the mesh by going to the new Memory Profilers detailed view, or you can find it via Resources.FindObjectOfTypeAll.
Thank you for the answer!
I am still a little bit confused. I understood how static batching works, but you were talking about the 'default' unity batching, right (the one that happens when an object is marked as 'static' at the start of the game)?
$$anonymous$$y problem is using the StaticBatchingUtillity.Combine() method. my goal is to achieve a batching that is closest to the batching the unity would've performed if the objects were static at start (they will be static when I perform the batching).
How can I achieve than?
Thanks again
It's more or less the same thing as what you call "default batching". Static batching is nothing more than taking a bunch of objects vertices and merging them into one huge mesh. Individual parts of the mesh can be rendered by specifying a different index buffer (which Unity takes care of, you have no control over that). So it should to my best knowledge work just the same.
Please tell me if I understood you correctly: I should just apply the Combine function on all the meshes with the same material? And than a big mesh will be created, but only the necessary parts of it will be drawn, right?
I don't know, but hey here's an idea. $$anonymous$$ake a test. $$anonymous$$ake a scene that contains a bunch of objects with one material. Call Combine. Check the # draw calls in Statistics Window. Now make a new scene and have a bunch of objects with different materials and call Combine. Check the # draw calls and ensure they are not too high (should be growing linearly with the number of unique materials you use).
Be a good Samaritan and come back with a comment of your findings, please :)
So I know this post is really old but I did just that - created a new scene with a bunch of objects using the same material.
Running the game just like that (no batching or anything, just running the game when the objects are all in view of the camera), I got these stats:
After applying Unity's default Static Batch (enabling the Static checkbox in their Inspector view), I got these stats:
Funny thing was there was no difference when doing the dynamic Static Batching (using StaticBatchingUtility.Combine(GA$$anonymous$$EOBJECT)), there was no difference from the other one, they were exactly identical.
Answer by haim96 · Dec 09, 2013 at 09:02 PM
i'm using StaticBatchingUtillity.Combine() in my project. with this you can batch several models under virtual one model.(well not really virtual since you can see it in the hierarchy when the project run). by this you should get less drawcall when drawing the batched object. keep in mind that static object that you combine cannot be moved in scene.
How do you use it? Can you give me some examples? I have a scene full of objects (trees, stones, bushes etc) scattered around. How should I approach it?
I'm answering from my phone so if you want code sample you have to wait or search on the web. But the idea is to create an array of your game object that you want to batch and then use it with the combine method. In my case I have random level made cubes and they are static. So I when I create them I put them in array and batch them. I can tell it reduced the amount of draw calls.