TalesOfNovariel/Assets/Scripts/NoiseGenerator.cs

231 lines
7.0 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NoiseGenerator
{
System.Random rand = new System.Random();
public void applyNoise(GameObject tile)
{
//resetMesh(tile);
Mesh mesh = tile.GetComponent<MeshFilter>().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<Tile>().setType(tiletype);
}
private void resetMesh(GameObject tile)
{
Mesh mesh = tile.GetComponent<MeshCollider>().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<MeshCollider>().sharedMesh = mesh;
}
private float[] calculateBasicSamples(GameObject tile)
{
Mesh mesh = tile.GetComponent<MeshFilter>().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<Tile>().getPosition().x + vertices[i].x / (vertices.Length - 1) * 10;
float yCord = tile.GetComponent<Tile>().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[] 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<MeshFilter>().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<MeshFilter>().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<MeshFilter>().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<MeshCollider>().sharedMesh = mesh;
}
}