Modifying mainTextureOffset increases draw calls

Hi All,

I’m working on a tile system for generating environments at runtime. The mechanism for generation is straight forward. I have a handful of tile prefabs (modeled in Blender) that are loaded, instantiated, and positioned in the scene. Each tile is 20x20 Unity units and I’m generating a 100x100 grid of them for testing. The tiles currently all share the same unlit mobile material containing a single 1024x1024 texture atlas. Each texture in the atlas is 256x256. By default the material’s tiling is set to 0.25, 0.25 and the offset to 0, 0. Tile generation looks like:

for(int i = 0; i < rows; i++)
{
	for(int j = 0; j < cols; j++)
	{
		UnityEngine.Object resource = resources[UnityEngine.Random.Range(0, resources.Count)];
		GameObject tile = (GameObject) GameObject.Instantiate(resource);
		tile.transform.position = new Vector3(startX + i * tileSize, 0, startZ + j * tileSize);
	}
}

The resources object contains the prefabs which were loaded with Resources.Load. Tile selection, as seen, is currently random. Nothing groundbreaking here and it works great. Looking at the stats there is only a single draw call and it absolutely flies when tested on an iPhone 4S. Now for the problem… If I modify each tile’s mainTextureOffset the draw calls shoot through the roof (in the thousands) and performance suffers. The code looks like:

// outside of the loop
List<Vector2> offsets = new List<Vector2>
{
	Vector2.zero,
	new Vector2(0.25f, 0f),
	new Vector2(0.5f, 0f),
	
	new Vector2(0.0f, 0.25f),
	new Vector2(0.25f, 0.25f),
	new Vector2(0.5f, 0.25f),

	...
};

...

// inside the loop
tile.renderer.material.mainTextureOffset = offsets[UnityEngine.Random.Range(0, offsets.Count)];

I would have thought that Unity would only need a single draw call or batch the calls since the material and texture remain the same but apparently that’s not the case. Is there anyway I can set this up so the tiles continue to require only a single draw call? Combine the tiles into a single mesh possibly?

Many thanks

Modifying the texture offset results in each individual tile getting a new material instance and therefore it will no longer batch. Based on what I see here, what you want to do instead is manipulate the uv coordinates of each tile and use a texture atlas.