# Batch meshes at runtime

> Batch static objects with the StaticBatchingUtility API, or dynamic GameObjects with dynamic batching.

For more information about batching, refer to [Introduction to batching meshes](/engine/6000.5/manual/analysis/graphics-performance-profiling/reduce-draw-calls/draw-call-batching/draw-call-batching.md).

> **Note:**
>
> Unity uses additional CPU memory to store the combined meshes, even if the meshes are the same. For example, marking trees as static in a dense forest environment can have a large impact on memory. If static batching uses too much memory, [combine meshes manually](/engine/6000.5/manual/analysis/graphics-performance-profiling/reduce-draw-calls/draw-call-batching/combining-meshes.md) instead.

## Batch static GameObjects at runtime

To batch static GameObjects at runtime, for example GameObjects you create procedurally, follow these steps:

1. Select each mesh you want to batch, then in the Editor window enable **Read/Write enabled**.

2. Use the [StaticBatchingUtility](/engine/6000.5/script-reference/unityengine/staticbatchingutility.md) API to batch the meshes. The [StaticBatchingUtility.Combine](/engine/6000.5/script-reference/unityengine/staticbatchingutility/combine.md) method combines GameObjects and prepares them for static batching.

> **Note:**
>
> To avoid the read/write mesh using double the amount of memory, you can now delete one copy of the mesh by calling the [`Mesh.UploadMeshData`](/engine/6000.5/script-reference/unityengine/mesh/uploadmeshdata.md) API with `markNoLongerReadable` set to `true`.

You don't need to enable the static batching setting in the URP asset, HDRP asset, or Editor.

If a mesh is culled because it's outside the camera view, Unity might split the batch into two batches, to avoid a gap in the combined vertex buffers.

You can only change the position, rotation, and scale of the whole batch at runtime, not the individual meshes.

## Batch moving GameObjects at runtime

> **Important:**
>
> The Built-In Render Pipeline is deprecated and will be made obsolete in a future release.
>
> It remains supported, including bug fixes and maintenance, through the full Unity 6.7 LTS lifecycle.
>
> For more information on migration, refer to [Migrating from the Built-In Render Pipeline to the Universal Render Pipeline](/engine/6000.5/manual/render-pipelines/universal-render-pipeline/introduction/installing-and-configuring-urp/upgrading-from-birp.md.md) and [Render pipeline feature comparison](/engine/6000.5/manual/render-pipelines/choose-a-render-pipeline/feature-comparison.md.md).

To batch moving GameObjects, enable dynamic batching.

> **Note:**
>
> Dynamic batching is deprecated. Refer to [Choose a draw call optimization method](/engine/6000.5/manual/analysis/graphics-performance-profiling/reduce-draw-calls/optimizing-draw-calls-choose-method.md) instead.

Follow these steps in the Built-In Render Pipeline:

1. Go to **Edit** > Editor > **Player**.
2. In the **Other Settings** section, enable Dynamic Batching.

Dynamic batching transforms all geometry into world space. To disable dynamic batching in a custom shader so you can access object space, enable **Disable batching** in the [Shader Import Settings](/engine/6000.5/manual/materials-and-shaders/class-shader-importer.md) window of the shader.

You can also disable batching by setting the `DisableBatching` tag to `True` in the subshader block of a shader. For example:

```
    SubShader {
        Tags { "DisableBatching" = "True" }
        ...
    }
```

## Additional resources

* [`SubShader` tags in ShaderLab reference](/engine/6000.5/manual/materials-and-shaders/shaders/reference/sl-reference/sl-sub-shader-object/tags.md)
