private void MeshIt(Vector3Int[] tiles, float[,] noiseMap) { Vector3 toTopLeft = -Vector3.right * .25f * hexWidth + Vector3.forward * .5f * hexHeight; Vector3 toTopRight = Vector3.right * .25f * hexWidth + Vector3.forward * .5f * hexHeight; Vector3 toRight = Vector3.right * .5f * hexWidth; Dictionary <Vector3Int, TileMeshData> tileVertexCodex = new Dictionary <Vector3Int, TileMeshData>(); int[] triangleIndices = new int[tiles.Length * 12]; int vertexIndex = 0; int triangleIndex = 0; float minX = float.MaxValue; float maxX = float.MinValue; float minY = float.MaxValue; float maxY = float.MinValue; foreach (Vector3Int tile in tiles) { Vector3 tileCenter = tilemap.GetCellCenterWorld(tile); Vector3 topLeftCorner = tileCenter + toTopLeft; Vector3 topRightCorner = tileCenter + toTopRight; Vector3 rightCorner = tileCenter + toRight; Vector3 bottomRightCorner = tileCenter - toTopLeft; Vector3 bottomLeftCorner = tileCenter - toTopRight; Vector3 leftCorner = tileCenter - toRight; minX = Mathf.Min(minX, leftCorner.x); maxX = Mathf.Max(maxX, rightCorner.x); minY = Mathf.Min(minY, bottomRightCorner.z); maxY = Mathf.Max(maxY, topRightCorner.z); TileMeshData tmd = new TileMeshData(); tmd.verticeIndices = new Tuple <Vector3, int> [6]; // look for shared vertices Vector3Int[] surroundingTiles = HexTools.GetSurroundingTilesOffset(tile); if (tileVertexCodex.TryGetValue(surroundingTiles[(int)Cardinality.N], out TileMeshData sharedData)) { tmd.verticeIndices[(int)IndexOrder.TopLeft] = new Tuple <Vector3, int>(topLeftCorner, sharedData.verticeIndices[(int)IndexOrder.BottomLeft].Item2); tmd.verticeIndices[(int)IndexOrder.TopRight] = new Tuple <Vector3, int>(topRightCorner, sharedData.verticeIndices[(int)IndexOrder.BottomRight].Item2); } if (tileVertexCodex.TryGetValue(surroundingTiles[(int)Cardinality.NE], out sharedData)) { tmd.verticeIndices[(int)IndexOrder.TopRight] = new Tuple <Vector3, int>(topRightCorner, sharedData.verticeIndices[(int)IndexOrder.Left].Item2); tmd.verticeIndices[(int)IndexOrder.Right] = new Tuple <Vector3, int>(rightCorner, sharedData.verticeIndices[(int)IndexOrder.BottomLeft].Item2); } if (tileVertexCodex.TryGetValue(surroundingTiles[(int)Cardinality.SE], out sharedData)) { tmd.verticeIndices[(int)IndexOrder.Right] = new Tuple <Vector3, int>(rightCorner, sharedData.verticeIndices[(int)IndexOrder.TopLeft].Item2); tmd.verticeIndices[(int)IndexOrder.BottomRight] = new Tuple <Vector3, int>(bottomRightCorner, sharedData.verticeIndices[(int)IndexOrder.Left].Item2); } if (tileVertexCodex.TryGetValue(surroundingTiles[(int)Cardinality.S], out sharedData)) { tmd.verticeIndices[(int)IndexOrder.BottomRight] = new Tuple <Vector3, int>(bottomRightCorner, sharedData.verticeIndices[(int)IndexOrder.TopRight].Item2); tmd.verticeIndices[(int)IndexOrder.BottomLeft] = new Tuple <Vector3, int>(bottomLeftCorner, sharedData.verticeIndices[(int)IndexOrder.TopLeft].Item2); } if (tileVertexCodex.TryGetValue(surroundingTiles[(int)Cardinality.SW], out sharedData)) { tmd.verticeIndices[(int)IndexOrder.BottomLeft] = new Tuple <Vector3, int>(bottomLeftCorner, sharedData.verticeIndices[(int)IndexOrder.Right].Item2); tmd.verticeIndices[(int)IndexOrder.Left] = new Tuple <Vector3, int>(leftCorner, sharedData.verticeIndices[(int)IndexOrder.TopRight].Item2); } if (tileVertexCodex.TryGetValue(surroundingTiles[(int)Cardinality.NW], out sharedData)) { tmd.verticeIndices[(int)IndexOrder.Left] = new Tuple <Vector3, int>(leftCorner, sharedData.verticeIndices[(int)IndexOrder.BottomRight].Item2); tmd.verticeIndices[(int)IndexOrder.TopLeft] = new Tuple <Vector3, int>(topLeftCorner, sharedData.verticeIndices[(int)IndexOrder.Right].Item2); } if (tmd.verticeIndices[(int)IndexOrder.TopLeft] == null) { tmd.verticeIndices[(int)IndexOrder.TopLeft] = new Tuple <Vector3, int>(topLeftCorner, vertexIndex++); } if (tmd.verticeIndices[(int)IndexOrder.TopRight] == null) { tmd.verticeIndices[(int)IndexOrder.TopRight] = new Tuple <Vector3, int>(topRightCorner, vertexIndex++); } if (tmd.verticeIndices[(int)IndexOrder.Right] == null) { tmd.verticeIndices[(int)IndexOrder.Right] = new Tuple <Vector3, int>(rightCorner, vertexIndex++); } if (tmd.verticeIndices[(int)IndexOrder.BottomRight] == null) { tmd.verticeIndices[(int)IndexOrder.BottomRight] = new Tuple <Vector3, int>(bottomRightCorner, vertexIndex++); } if (tmd.verticeIndices[(int)IndexOrder.BottomLeft] == null) { tmd.verticeIndices[(int)IndexOrder.BottomLeft] = new Tuple <Vector3, int>(bottomLeftCorner, vertexIndex++); } if (tmd.verticeIndices[(int)IndexOrder.Left] == null) { tmd.verticeIndices[(int)IndexOrder.Left] = new Tuple <Vector3, int>(leftCorner, vertexIndex++); } tileVertexCodex[tile] = tmd; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.TopLeft].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.TopRight].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.BottomRight].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.TopRight].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.Right].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.BottomRight].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.BottomRight].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.BottomLeft].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.TopLeft].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.BottomLeft].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.Left].Item2; triangleIndices[triangleIndex++] = tmd.verticeIndices[(int)IndexOrder.TopLeft].Item2; } Vector3[] vertices = new Vector3[vertexIndex]; int mapX = noiseMap.GetLength(0); int mapY = noiseMap.GetLength(1); int i = 0; foreach (var kvp in tileVertexCodex) { TileMeshData tmd = kvp.Value; foreach (Tuple <Vector3, int> verts in tmd.verticeIndices) { if (vertices[verts.Item2] != Vector3.zero) { continue; // If the tilemap is positioned at 0,0 there should never be a vertex there } Vector3 pos = verts.Item1; float percentX = Mathf.InverseLerp(minX, maxX, pos.x); float percentY = Mathf.InverseLerp(minY, maxY, pos.z); int x = Mathf.RoundToInt(percentX * (mapX - 1)); int y = Mathf.RoundToInt(percentY * (mapY - 1)); vertices[verts.Item2] = pos + new Vector3(0, noiseMap[x, y] * 5, 0); ++i; } } Mesh mesh = new Mesh(); mesh.vertices = vertices; mesh.triangles = triangleIndices; mesh.RecalculateBounds(); GetComponent <MeshFilter>().sharedMesh = mesh; Debug.Log("i: " + i + " vertices: " + vertices.Length + " triangles: " + (triangleIndices.Length / 3)); }