public static void BuildForChunk(tk2dTileMap tileMap, SpriteChunk chunk, ColorChunk colorChunk, bool useColor, bool skipPrefabs, int baseX, int baseY) { List <Vector3> meshVertices = new List <Vector3>(); List <Color> meshColors = new List <Color>(); List <Vector2> meshUvs = new List <Vector2>(); //List<int> meshIndices = new List<int>(); int[] spriteIds = chunk.spriteIds; Vector3 tileSize = tileMap.data.tileSize; int spriteCount = tileMap.SpriteCollectionInst.spriteDefinitions.Length; Object[] tilePrefabs = tileMap.data.tilePrefabs; Color32 clearColor = (useColor && tileMap.ColorChannel != null)?tileMap.ColorChannel.clearColor:Color.white; // revert to no color mode (i.e. fill with clear color) when there isn't a color channel, or it is empty if (colorChunk == null || colorChunk.colors.Length == 0) { useColor = false; } int x0, x1, dx; int y0, y1, dy; BuilderUtil.GetLoopOrder(tileMap.data.sortMethod, tileMap.partitionSizeX, tileMap.partitionSizeY, out x0, out x1, out dx, out y0, out y1, out dy); float xOffsetMult = 0.0f, yOffsetMult = 0.0f; tileMap.data.GetTileOffset(out xOffsetMult, out yOffsetMult); List <int>[] meshIndices = new List <int> [tileMap.SpriteCollectionInst.materials.Length]; for (int j = 0; j < meshIndices.Length; ++j) { meshIndices[j] = new List <int>(); } int colorChunkSize = tileMap.partitionSizeX + 1; for (int y = y0; y != y1; y += dy) { float xOffset = ((baseY + y) & 1) * xOffsetMult; for (int x = x0; x != x1; x += dx) { int spriteId = spriteIds[y * tileMap.partitionSizeX + x]; int tile = BuilderUtil.GetTileFromRawTile(spriteId); bool flipH = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.FlipX); bool flipV = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.FlipY); Vector3 currentPos = new Vector3(tileSize.x * (x + xOffset), tileSize.y * y, 0); if (tile < 0 || tile >= spriteCount) { continue; } if (skipPrefabs && tilePrefabs[tile]) { continue; } var sprite = tileMap.SpriteCollectionInst.spriteDefinitions[tile]; int baseVertex = meshVertices.Count; for (int v = 0; v < sprite.positions.Length; ++v) { Vector3 flippedPos = BuilderUtil.FlipSpriteVertexPosition(tileMap, sprite, sprite.positions[v], flipH, flipV); if (useColor) { Color tileColorx0y0 = colorChunk.colors[y * colorChunkSize + x]; Color tileColorx1y0 = colorChunk.colors[y * colorChunkSize + x + 1]; Color tileColorx0y1 = colorChunk.colors[(y + 1) * colorChunkSize + x]; Color tileColorx1y1 = colorChunk.colors[(y + 1) * colorChunkSize + (x + 1)]; Vector3 centeredSpriteVertex = flippedPos - sprite.untrimmedBoundsData[0]; Vector3 alignedSpriteVertex = centeredSpriteVertex + tileMap.data.tileSize * 0.5f; float tileColorX = Mathf.Clamp01(alignedSpriteVertex.x / tileMap.data.tileSize.x); float tileColorY = Mathf.Clamp01(alignedSpriteVertex.y / tileMap.data.tileSize.y); Color color = Color.Lerp( Color.Lerp(tileColorx0y0, tileColorx1y0, tileColorX), Color.Lerp(tileColorx0y1, tileColorx1y1, tileColorX), tileColorY); meshColors.Add(color); } else { meshColors.Add(clearColor); } meshVertices.Add(currentPos + flippedPos); meshUvs.Add(sprite.uvs[v]); } bool reverseIndices = false; // flipped? if (flipH) { reverseIndices = !reverseIndices; } if (flipV) { reverseIndices = !reverseIndices; } List <int> indices = meshIndices[sprite.materialId]; for (int i = 0; i < sprite.indices.Length; ++i) { int j = reverseIndices ? (sprite.indices.Length - 1 - i) : i; indices.Add(baseVertex + sprite.indices[j]); } } } if (chunk.mesh == null) { chunk.mesh = new Mesh(); } chunk.mesh.vertices = meshVertices.ToArray(); chunk.mesh.uv = meshUvs.ToArray(); chunk.mesh.colors = meshColors.ToArray(); List <Material> materials = new List <Material>(); int materialId = 0; int subMeshCount = 0; foreach (var indices in meshIndices) { if (indices.Count > 0) { materials.Add(tileMap.SpriteCollectionInst.materials[materialId]); subMeshCount++; } materialId++; } if (subMeshCount > 0) { chunk.mesh.subMeshCount = subMeshCount; chunk.gameObject.GetComponent <Renderer>().materials = materials.ToArray(); int subMeshId = 0; foreach (var indices in meshIndices) { if (indices.Count > 0) { chunk.mesh.SetTriangles(indices.ToArray(), subMeshId); subMeshId++; } } } chunk.mesh.RecalculateBounds(); var meshFilter = chunk.gameObject.GetComponent <MeshFilter>(); meshFilter.sharedMesh = chunk.mesh; }
// Builds an unoptimized mesh for this chunk static void BuildLocalMeshForChunk(tk2dTileMap tileMap, SpriteChunk chunk, int baseX, int baseY, ref Vector3[] vertices, ref int[] indices) { List <Vector3> vertexList = new List <Vector3>(); List <int> indexList = new List <int>(); int spriteCount = tileMap.SpriteCollectionInst.spriteDefinitions.Length; Vector3 tileSize = tileMap.data.tileSize; var tilePrefabs = tileMap.data.tilePrefabs; float xOffsetMult = 0.0f, yOffsetMult = 0.0f; tileMap.data.GetTileOffset(out xOffsetMult, out yOffsetMult); var chunkData = chunk.spriteIds; for (int y = 0; y < tileMap.partitionSizeY; ++y) { float xOffset = ((baseY + y) & 1) * xOffsetMult; for (int x = 0; x < tileMap.partitionSizeX; ++x) { int spriteId = chunkData[y * tileMap.partitionSizeX + x]; int spriteIdx = BuilderUtil.GetTileFromRawTile(spriteId); Vector3 currentPos = new Vector3(tileSize.x * (x + xOffset), tileSize.y * y, 0); if (spriteIdx < 0 || spriteIdx >= spriteCount) { continue; } if (tilePrefabs[spriteIdx]) { continue; } bool flipH = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.FlipX); bool flipV = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.FlipY); bool reverseIndices = false; if (flipH) { reverseIndices = !reverseIndices; } if (flipV) { reverseIndices = !reverseIndices; } var spriteData = tileMap.SpriteCollectionInst.spriteDefinitions[spriteIdx]; int baseVertexIndex = vertexList.Count; if (spriteData.colliderType == tk2dSpriteDefinition.ColliderType.Box) { Vector3 origin = spriteData.colliderVertices[0]; Vector3 extents = spriteData.colliderVertices[1]; Vector3 min = origin - extents; Vector3 max = origin + extents; Vector3[] pos = new Vector3[8]; pos[0] = new Vector3(min.x, min.y, min.z); pos[1] = new Vector3(min.x, min.y, max.z); pos[2] = new Vector3(max.x, min.y, min.z); pos[3] = new Vector3(max.x, min.y, max.z); pos[4] = new Vector3(min.x, max.y, min.z); pos[5] = new Vector3(min.x, max.y, max.z); pos[6] = new Vector3(max.x, max.y, min.z); pos[7] = new Vector3(max.x, max.y, max.z); for (int i = 0; i < 8; ++i) { Vector3 flippedPos = BuilderUtil.FlipSpriteVertexPosition(tileMap, spriteData, pos[i], flipH, flipV); vertexList.Add(flippedPos + currentPos); } // int[] indicesBack = { 0, 1, 2, 2, 1, 3, 6, 5, 4, 7, 5, 6, 3, 7, 6, 2, 3, 6, 4, 5, 1, 4, 1, 0 }; int[] indicesFwd = { 2, 1, 0, 3, 1, 2, 4, 5, 6, 6, 5, 7, 6, 7, 3, 6, 3, 2, 1, 5, 4, 0, 1, 4 }; var srcIndices = indicesFwd; for (int i = 0; i < srcIndices.Length; ++i) { int j = reverseIndices ? (srcIndices.Length - 1 - i) : i; indexList.Add(baseVertexIndex + srcIndices[j]); } } else if (spriteData.colliderType == tk2dSpriteDefinition.ColliderType.Mesh) { for (int i = 0; i < spriteData.colliderVertices.Length; ++i) { Vector3 flippedPos = BuilderUtil.FlipSpriteVertexPosition(tileMap, spriteData, spriteData.colliderVertices[i], flipH, flipV); vertexList.Add(flippedPos + currentPos); } var srcIndices = spriteData.colliderIndicesFwd; for (int i = 0; i < srcIndices.Length; ++i) { int j = reverseIndices ? (srcIndices.Length - 1 - i) : i; indexList.Add(baseVertexIndex + srcIndices[j]); } } } } vertices = vertexList.ToArray(); indices = indexList.ToArray(); }