public void generateMap(bool fill = true) { // have to force it to low value mapChunkSize = (fill ? 101 : 241); float heightCheck = regions[0].height; List <int> fencePositions = new List <int>(); float[,] map = perlinMap.generateMap(mapChunkSize, mapChunkSize, seed, scale, octaves, persistence, lacunarity, offset); // store whether that area is livable int[,] livable = new int[mapChunkSize, mapChunkSize]; Color[] colormap = new Color[mapChunkSize * mapChunkSize]; for (int h = 0; h < mapChunkSize; ++h) { for (int w = 0; w < mapChunkSize; ++w) { // begin searching for livable areas if (map[w, h] <= cityHigh && map[w, h] >= cityLow) { livable[w, h] = 1; } else { livable[w, h] = 0; } float currentHeight = map[w, h]; for (int i = 0; i < regions.Length; ++i) { if (currentHeight <= regions[i].height) { Color colour = regions[i].color; if (i == 1 && showBorder) { // check left if (w > 0 && map[w - 1, h] <= heightCheck) { //colormap[h * mapChunkSize + w - 1] = Color.black; fencePositions.Add(h * mapChunkSize + (w - 1)); } // check top if (h > 0 && map[w, h - 1] <= heightCheck) { //colormap[(h - 1) * mapChunkSize + w] = Color.black; fencePositions.Add((h - 1) * mapChunkSize + w); } } else if (i == 0 && showBorder) { // check left if (w > 0 && map[w - 1, h] > heightCheck) { fencePositions.Add(h * mapChunkSize + w); //colour = Color.black; } // check top if (h > 0 && map[w, h - 1] > heightCheck) { fencePositions.Add(h * mapChunkSize + w); //colour = Color.black; } } //else if (i == 3 && placeModels) //{ // treePositions.Add(h * mapChunkSize + w); //} colormap[h * mapChunkSize + w] = colour; break; } } } } display_map display = FindObjectOfType <display_map>(); if (draw_mode == DrawMode.NoiseMap) { display.DrawTexture(TextureGenerator.TextureFromHeightMap(map)); } else if (draw_mode == DrawMode.ColorMap) { display.DrawTexture(TextureGenerator.TextureFromColorMap(colormap, mapChunkSize, mapChunkSize)); } else if (draw_mode == DrawMode.Mesh) { MeshData md = MeshGenerator.generate_terrain_mesh(map, meshHeightMultiplier, levelOfDetails, meshHeightCurve); display.DrawMesh(md, TextureGenerator.TextureFromColorMap(colormap, mapChunkSize, mapChunkSize)); for (int i = 0; i < fencePositions.Count; ++i) { Vector3 pos = md.vertices[fencePositions[i]]; //pos.x *= 10; //pos.z *= 10; GameObject fence = Instantiate(fences[0], pos, Quaternion.identity); } // if (fill) { // plant some vegetations! // find the max value in map int max_w = -1, max_h = -1; float max = -1f; for (int w = 0; w < mapChunkSize; ++w) { for (int h = 0; h < mapChunkSize; ++h) { if (map[w, h] > max) { max = map[w, h]; max_w = w; max_h = h; } // generate some stuff on the ground if (map[w, h] >= 0.3f && map[w, h] <= 0.6f) { float dice = Random.Range(0.0f, 1.0f); if (dice < 0.08f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(trees[0], treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice > 0.08f && dice < 0.1f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(trees[1], treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice > 0.1f && dice < 0.15f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(trees[2], treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice > 0.15f && dice < 0.25f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(trees[3], treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice > 0.25f && dice < 0.35f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(trees[4], treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice > 0.35f && dice < 0.50f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(trees[5], treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice > 0.50f && dice < 0.70f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(trees[6], treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice > 0.70f && dice < 0.80f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(trees[8], treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice > 0.80f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(trees[9], treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } } else if (map[w, h] >= 0.83f && map[w, h] <= 0.87f) { Vector3 treePos = new Vector3(w - 50.0f, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, (mapChunkSize - h) - 50.0f); Instantiate(fences[0], treePos, Quaternion.identity); } } } // procedurally generate city List <int[]> coords = squares(livable, villageSizeCutoff); foreach (int[] j in coords) { int cityWidth = Mathf.Abs(j[3] - j[1]); int cityHeight = Mathf.Abs(j[0] - j[2]); int buildingFootprint = 2; float[,] citygrid = new float[cityWidth, cityHeight]; for (int h = 0; h < cityHeight; ++h) { for (int w = 0; w < cityWidth; ++w) { //citygrid[w, h] = (int)(Mathf.PerlinNoise(w / 10.0f, h / 10.0f) * 10.0f); citygrid[w, h] = Random.Range(0.0f, 1.0f); } } // build city float mapY = meshHeightCurve.Evaluate(map[j[0], j[1]]) * meshHeightMultiplier; for (int h = 0; h < cityHeight; h++) { for (int w = 0; w < cityWidth; w++) { float result = citygrid[w, h]; Debug.Log(result); Vector3 position = new Vector3((w * buildingFootprint + j[0]) - 50.0f, mapY, (mapChunkSize - (h * buildingFootprint + j[1])) - 50.0f); if (w * buildingFootprint < cityWidth && h * buildingFootprint < cityHeight) { if (result < 0.2f) { Instantiate(buildings[0], position, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (result > 0.2f && result < 0.3f) { Instantiate(buildings[1], position, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (result > 0.3f && result < 0.4f) { Instantiate(buildings[2], position, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (result > 0.4f && result < 0.5f) { Instantiate(buildings[3], position, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (result > 0.5f && result < 0.6f) { Instantiate(buildings[4], position, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (result > 0.6f && result < 0.7f) { Instantiate(buildings[5], position, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (result > 0.7f && result < 0.8f) { Instantiate(buildings[6], position, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (result > 0.8f && result < 0.9f) { Instantiate(buildings[7], position, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (result > 0.9f) { Instantiate(buildings[8], position, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } } } } } } } }
public void generateMap(bool fill = true) { // have to force it to low value mapChunkSize = (fill ? 101 : 241); float[,] map = perlinMap.generateMap(mapChunkSize, mapChunkSize, seed, scale, octaves, persistence, lacunarity, offset); // store whether that area is livable int [,] livable = new int [mapChunkSize, mapChunkSize]; Color[] colormap = new Color[mapChunkSize * mapChunkSize]; for (int h = 0; h < mapChunkSize; ++h) { for (int w = 0; w < mapChunkSize; ++w) { // begin searching for livable areas if (map[w, h] <= cityHigh && map[w, h] >= cityLow) { livable[w, h] = 1; } else { livable[w, h] = 0; } float currentHeight = map[w, h]; for (int i = 0; i < regions.Length; ++i) { if (currentHeight <= regions[i].height) { colormap[h * mapChunkSize + w] = regions[i].color; break; } } } } display_map display = FindObjectOfType <display_map>(); if (draw_mode == DrawMode.NoiseMap) { display.DrawTexture(TextureGenerator.TextureFromHeightMap(map)); } else if (draw_mode == DrawMode.ColorMap) { display.DrawTexture(TextureGenerator.TextureFromColorMap(colormap, mapChunkSize, mapChunkSize)); } else if (draw_mode == DrawMode.Mesh) { display.DrawMesh(MeshGenerator.generate_terrain_mesh(map, meshHeightMultiplier, levelOfDetails, meshHeightCurve), TextureGenerator.TextureFromColorMap(colormap, mapChunkSize, mapChunkSize)); if (fill) { // instantiate a smaug model on the highest mountain! // plant some vegetations! // find the max value in map int max_w = -1, max_h = -1; float max = -1f; for (int w = 0; w < mapChunkSize; ++w) { for (int h = 0; h < mapChunkSize; ++h) { if (map[w, h] > max) { max = map[w, h]; max_w = w; max_h = h; } // generate some stuff on the ground if (map[w, h] >= 0.5f && map[w, h] <= 0.7f) { float dice = Random.Range(0.0f, 1.0f); if (dice < 0.05f) { Vector3 grassPos = new Vector3(w, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, mapChunkSize - h); Instantiate(grass, grassPos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice < 0.08f) { Vector3 treePos = new Vector3(w, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, mapChunkSize - h); Instantiate(tree, treePos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice < 0.12f) { Vector3 mushroomPos = new Vector3(w, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, mapChunkSize - h); Instantiate(mushroom, mushroomPos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } else if (dice < 0.15f) { Vector3 sheepPos = new Vector3(w, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, mapChunkSize - h); Instantiate(sheep, sheepPos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } } else if (map[w, h] <= 0.35f) { float dice = Random.Range(0.0f, 1.0f); if (dice < 0.005f) { Vector3 boatPos = new Vector3(w, meshHeightCurve.Evaluate(map[w, h]) * meshHeightMultiplier, mapChunkSize - h); Instantiate(boat, boatPos, Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f)); } } } } // create position vector for smaug Vector3 smaugPos = new Vector3(max_w, meshHeightCurve.Evaluate(map[max_w, max_h]) * meshHeightMultiplier - 2.0f, mapChunkSize - max_h - 2.0f); Instantiate(smaug, smaugPos, smaug.transform.rotation); // procedurally generate city List <int[]> coords = squares(livable, villageSizeCutoff); foreach (int[] i in coords) { int cityWidth = Mathf.Abs(i[3] - i[1]); int cityHeight = Mathf.Abs(i[0] - i[2]); int buildingFootprint = 2; int[,] citygrid = new int[cityWidth, cityHeight]; for (int h = 0; h < cityHeight; ++h) { for (int w = 0; w < cityWidth; ++w) { citygrid[w, h] = (int)(Mathf.PerlinNoise(w / 10.0f, h / 10.0f) * 10.0f); } } // build city float mapY = meshHeightCurve.Evaluate(map[i[0], i[1]]) * meshHeightMultiplier; for (int h = 0; h < cityHeight; h++) { for (int w = 0; w < cityWidth; w++) { int result = citygrid[w, h]; Debug.Log(result); Vector3 position = new Vector3(w * buildingFootprint + i[0], mapY, mapChunkSize - (h * buildingFootprint + i[1])); if (w * buildingFootprint < cityWidth && h * buildingFootprint < cityHeight) { if (result < 2) { Instantiate(buildings[0], position, Quaternion.Euler(-90.0f, 0.0f, 0.0f)); } else if (result < 4) { Instantiate(buildings[1], position, Quaternion.Euler(-90.0f, 0.0f, 0.0f)); } else if (result < 6) { Instantiate(buildings[2], position, Quaternion.Euler(-90.0f, 0.0f, 0.0f)); } else if (result < 8) { Instantiate(buildings[3], position, Quaternion.Euler(-90.0f, 0.0f, 0.0f)); } else if (result < 10) { Instantiate(buildings[4], position, Quaternion.Euler(-90.0f, 0.0f, 180.0f)); } } } } } } } }