using Assets.Scripts; using System.Collections; using System.Collections.Generic; using UnityEngine; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Linq; public class NoiseGenerator { System.Random rand = new System.Random(); public void applyNoise(GameObject tile, string name, Dictionary map) { /*if(name.Length > 0){ applyCityNoise(tile); } else{ applyNormalNoise(tile, map); }*/ applyNormalNoise(tile, map); } private void applyCityNoise(GameObject tile) { //resetMesh(tile); Mesh mesh = tile.GetComponent().mesh; Vector3[] vertices = mesh.vertices; float[] samples; Color32[] colors; int chance = rand.Next(1, 101); samples = calculateSamplesCity(tile); string tiletype = "City"; colors = new Color32[samples.Length]; for (int i = 0; i < samples.Length; i++) { colors[i] = new Color32(0, 185, 0, 255); } for (int i = 0; i < samples.Length; i++) { vertices[i].y = samples[i] * 3; } applyMesh(tile, vertices, mesh, colors); tile.GetComponent().setType(tiletype); } private void applyNormalNoise(GameObject tile, Dictionary map) { //resetMesh(tile); Mesh mesh = tile.GetComponent().mesh; Vector3[] vertices = mesh.vertices; float[] samples; Color32[] colors; Color32 low; Color32 high; int chance = rand.Next(1, 101); string tiletype = ""; if (chance > 85 && chance <= 100) { samples = calculateSamplesForest(tile); low = new Color32(0, 150, 0, 255); high = new Color32(0, 110, 20, 255); tiletype = "Forest"; } else if (chance > 70 && chance <= 85) { samples = calculateSamplesMountain(tile); low = new Color32(0, 150, 0, 255); high = new Color32(140, 140, 140, 255); tiletype = "Mountain"; } else if (chance > 55 && chance <= 70) { samples = calculateSamplesLake(tile); low = new Color32(30, 110, 190, 255); high = new Color32(0, 150, 0, 255); tiletype = "Lake"; } else if (chance > 40 && chance <= 55) { samples = calculateSamplesRiver(tile); low = new Color32(30, 160, 190, 255); high = new Color32(0, 150, 0, 255); tiletype = "River"; } else { samples = calculateSamplesPlane(tile); low = new Color32(0, 150, 0, 255); high = new Color32(0, 185, 0, 255); tiletype = "Plane"; } float lowestValue = 10; float highestValue = 0; for (int i = 0; i < samples.Length; i++) { if (lowestValue > samples[i]) { lowestValue = samples[i]; } if (highestValue < samples[i]) { highestValue = samples[i]; } } float modifier = highestValue - lowestValue; colors = new Color32[samples.Length]; for (int i = 0; i < samples.Length; i++) { colors[i] = Color32.Lerp(low, high, (1 / modifier) * (samples[i] - lowestValue)); } for (int i = 0; i < samples.Length; i++) { vertices[i].y = samples[i] * 3; } applyMesh(tile, vertices, mesh, colors); tile.GetComponent().setType(tiletype); } private void resetMesh(GameObject tile) { Mesh mesh = tile.GetComponent().sharedMesh; Vector3[] vertices = mesh.vertices; for (int i = 0; i < vertices.Length; i++) { vertices[i].y = 0; } mesh.vertices = vertices; mesh.RecalculateBounds(); mesh.RecalculateNormals(); tile.GetComponent().sharedMesh = mesh; } private float[] calculateBasicSamples(GameObject tile) { Mesh mesh = tile.GetComponent().mesh; Vector3[] vertices = mesh.vertices; float[] samples = new float[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { if (vertices[i].x != 5 && vertices[i].z != 5 && vertices[i].x != -5 && vertices[i].z != -5) { float xCord = tile.GetComponent().getPosition().x + vertices[i].x / (vertices.Length - 1) * 10; float yCord = tile.GetComponent().getPosition().z + vertices[i].z / (vertices.Length - 1) * 10; float sample = Mathf.PerlinNoise(xCord, yCord) - 0.1f * rand.Next(0, 6); samples[i] = sample; } } return samples; } private float[] calculateSamplesCity(GameObject tile){ Mesh mesh = tile.GetComponent().mesh; Vector3[] vertices = mesh.vertices; float[] samples = new float[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { samples[i] = 0; } return samples; } private float[] calculateSamplesPlane(GameObject tile) { float[] samples = calculateBasicSamples(tile); return samples; } private float[] calculateSamplesForest(GameObject tile) { float[] samples = calculateBasicSamples(tile); return samples; } private float[] calculateSamplesMountain(GameObject tile) { Mesh mesh = tile.GetComponent().mesh; Vector3[] vertices = mesh.vertices; float[] samples = calculateBasicSamples(tile); int amount = rand.Next(1, 5); int index = 0; for (int i = 0; i < amount; i++) { do { index = rand.Next(0, samples.Length); if (vertices[index].x != 5 && vertices[index].z != 5 && vertices[index].x != -5 && vertices[index].z != -5) { samples[index] = 3; break; } } while (true); } return samples; } private float[] calculateSamplesRiver(GameObject tile) { Mesh mesh = tile.GetComponent().mesh; Vector3[] vertices = mesh.vertices; float[] samples = calculateBasicSamples(tile); bool isVertical = (rand.Next(0,2) == 0 ? true : false); int startX = 0; int startZ = 0; if (isVertical) { startZ = (rand.Next(0, 2) == 0 ? 4 : -4); startX = rand.Next(-4, 5); } else { startZ = rand.Next(-4, 5); startX = (rand.Next(0, 2) == 0 ? 4 : -4); } for (int k = 0; k < vertices.Length; k++) { if (isVertical) { if (Mathf.Round(vertices[k].x) == startX && Mathf.Round(vertices[k].z) != 5 && Mathf.Round(vertices[k].z) != -5) { samples[k] = samples[k] - rand.Next(2, 4) + 0.5f; } } else { if (Mathf.Round(vertices[k].x) != 5 && Mathf.Round(vertices[k].x) != -5 && Mathf.Round(vertices[k].z) == startZ) { samples[k] = samples[k] - rand.Next(2, 4) + 0.5f; } } } return samples; } private float[] calculateSamplesLake(GameObject tile) { Mesh mesh = tile.GetComponent().mesh; Vector3[] vertices = mesh.vertices; float[] samples = calculateBasicSamples(tile); int randX = rand.Next(-3, 4); int randZ = rand.Next(-3, 4); for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { for (int k = 0; k < vertices.Length; k++) { if (Mathf.Round(vertices[k].x) == randX+i && Mathf.Round(vertices[k].z) == randZ+j) { samples[k] = samples[k] - rand.Next(1,3) - 0.25f * rand.Next(0,4); break; } } } } return samples; } private void applyMesh(GameObject tile, Vector3[] vertices, Mesh mesh, Color32[] colors) { mesh.vertices = vertices; mesh.RecalculateBounds(); mesh.RecalculateNormals(); mesh.colors32 = colors; tile.GetComponent().sharedMesh = mesh; } public void saveTile(GameObject tile, string path) { string result = ""; Vector3[] vertices = tile.GetComponent().mesh.vertices; Color32[] colors = tile.GetComponent().mesh.colors32; result = result + "\"vertices\": {\r\n"; for (int i = 0; i < vertices.Length; i++) { result = result + FileHandler.generateJSON("vertice"+i, "\"" + vertices[i].x + "/" + vertices[i].y + "/" + vertices[i].z + "\""); if (i < vertices.Length - 1) { result = result + ",\r\n"; } } result = result + "\r\n},\"colors\": {\r\n"; for (int i = 0; i < colors.Length; i++) { result = result + FileHandler.generateJSON("color" + i, "\"" + colors[i].r + "/" + colors[i].g + "/" + colors[i].b + "/" + colors[i].a + "\""); if (i < colors.Length - 1) { result = result + ",\r\n"; } } result = result + "\r\n}\r\n}"; FileHandler.saveNoise(result, path); } public void loadTile(GameObject tile, JToken jsonVertices, JToken jsonColors) { var jsonData = JObject.Parse(jsonColors.ToString()).Children(); List colorTokens = jsonData.Children().ToList(); jsonData = JObject.Parse(jsonVertices.ToString()).Children(); List verticeTokens = jsonData.Children().ToList(); Color32[] colors = new Color32[colorTokens.Count]; Vector3[] vertices = new Vector3[verticeTokens.Count]; JToken current; string[] parts; for(int i = 0; i < colorTokens.Count;i++) { current = colorTokens[i]; parts = current.Value().Split('/'); colors[i] = new Color32(byte.Parse(parts[0]), byte.Parse(parts[1]), byte.Parse(parts[2]), byte.Parse(parts[3])); } for (int i = 0; i < verticeTokens.Count; i++) { current = verticeTokens[i]; parts = current.Value().Split('/'); vertices[i] = new Vector3(float.Parse(parts[0]), float.Parse(parts[1]), float.Parse(parts[2])); } applyMesh(tile, vertices, tile.GetComponent().mesh, colors); } }