public void Rebuild(int sleepMs = 0) { if (!needRebuild) { return; } var parentMap = gameObject.GetComponentInParent <TestMap>(); if (start.x < 0 || start.y < 0 || end.x < 0 || end.y < 0) { return; // will cause fatal error } mapData = DDA.GetTilesBetween(start, end); if (mapData == null) { return; } float tileSize = parentMap.tileSize; if (thread != null && thread.IsAlive) { return; } thread = new Thread(() => { Thread.Sleep(sleepMs); MeshDraft chunkMesh = new MeshDraft(); int gameObjectCount = 0; foreach (var tile in mapData.tiles) { //if (!tile.seen) continue; MeshDraft tileMesh = parentMap.GetCachedTerMesh(tile.ter); // probably will not work in non main thread if (tileMesh != null) { if (chunkMesh.vertexCount + tileMesh.vertexCount < 65000) { MeshDraft tileMeshCopy = tileMesh.Clone(); tileMeshCopy.Move(new Vector3((tile.loc.x - start.x) * tileSize, tile.loc.y * tileSize, (tile.loc.z - start.y) * tileSize)); chunkMesh.Add(tileMeshCopy); } else { AssignMesh(chunkMesh, "subchunk" + gameObjectCount.ToString("D2")); gameObjectCount++; chunkMesh = new MeshDraft(); } } } if (chunkMesh.vertexCount > 0 && gameObjectCount == 0) { AssignMesh(chunkMesh); } else if (chunkMesh.vertexCount > 0) { AssignMesh(chunkMesh, "subchunk" + gameObjectCount.ToString("D2")); } }); thread.Start(); }