public static Mesh GenerateHexagonMesh(float radius, float border, int startX, int startY, int chunkWidth, int chunkHeight, int mapWidth, int mapHeight, float[] heightMap, Func <float, Color> colorFunction, Func <float, float> elevationFunction) { var meshData = new HexMeshData(radius, border); for (int dy = 0; dy < chunkHeight && (startY + dy) < mapHeight; dy++) { for (int dx = 0; dx < chunkWidth && (startX + dx) < mapWidth; dx++) { int x = startX + dx; int y = startY + dy; var index = (y * mapWidth) + x; var xOffset = x + y * 0.5f - (int)(y / 2); var center = new Vector3(xOffset * meshData.InnerRadius * 2, 0, y * meshData.OuterRadius * 1.5f); for (var direction = 0; direction < 6; direction++) { var elevation = elevationFunction?.Invoke(heightMap[index]) ?? 0; var previousNeighborElevation = elevation; var neighborElevation = elevation; var nextNeighborElevation = elevation; var neighbor = GetNeighbor(index, (HexDirection)direction, mapWidth, mapHeight); if (neighbor != -1) { neighborElevation = Mathf.Min(elevation, elevationFunction?.Invoke(heightMap[neighbor]) ?? 0); } neighbor = GetNeighbor(index, ((HexDirection)direction).Previous(), mapWidth, mapHeight); if (neighbor != -1) { previousNeighborElevation = Mathf.Min(elevation, elevationFunction?.Invoke(heightMap[neighbor]) ?? 0); } neighbor = GetNeighbor(index, ((HexDirection)direction).Next(), mapWidth, mapHeight); if (neighbor != -1) { nextNeighborElevation = Mathf.Min(elevation, elevationFunction?.Invoke(heightMap[neighbor]) ?? 0); } center.y = elevation; var color = colorFunction?.Invoke(heightMap[index]) ?? Color.white; var uv = new Vector2(x / (float)mapWidth, y / (float)mapHeight); AddTriangle(meshData, center, uv, neighborElevation, previousNeighborElevation, nextNeighborElevation, (HexDirection)direction, color); } } } return(meshData.CreateMesh()); }