public Transform tile;//only for show, but it must be 1 by 1.
public Transform parent;
public int x;//size x
public int y;//size y
public float water_percent = 0.28f;
public float humidity_plus = 0.0f;
public float mountain_threshold = 0.7f;
public AnimationCurve height_multiplier; //this is used to sharpen mountains and flatten valleys.
//Ideally the curve should be 0y in 0x and 1y in 1x, and below 0.5 for most of its lenght
public float he_zoom = 10f;
public float he_factor = 3f; //1.8 to 4 look good
public Vector2 he_seed;
public float hu_zoom = 10f;
public float hu_factor = 1.8f; //1.8 to 10 look good
public Vector2 hu_seed=new Vector2(100,100);
public float tmp_zoom = 10f;
public float tmp_factor = 1.8f;
public Vector2 tmp_seed = new Vector2(200, 200);
float[,] he_array;
float[,] hu_array;
float[,] te_array;
Transform[,] tiles;
public Color Forest;
public Color Desert;
public Color Sea;
public Color Snow;
public Color Peak;
public Color Plains;
public string col_type = "g"; //g for gradient,l for single color,r for random. High enough values of "factor" makes random unnecessary
// Use this for initialization
void Start()
{
MakeArrays();
MakeTiles();
}
// Update is called once per frame
void Update()
{
RecalculateArray();
PaintTiles();
}
//calculate the value of an element of the array based on noise and location
float FractalNoise(int i, int j, float zoom, float factor, Vector2 seed)
{
i = i + Mathf.RoundToInt(seed.x * zoom);
j = j + Mathf.RoundToInt(seed.y * zoom);
//fractal behavior occurs here. Everything else is parameter fine-tuning
return 0
+ Mathf.PerlinNoise(i / zoom, j / zoom) / 3
+ Mathf.PerlinNoise(i / (zoom / factor), j / (zoom / factor)) / 3
+ Mathf.PerlinNoise(i / (zoom / factor * factor), j / (zoom / factor * factor)) / 3;
}
float FractalNoiseRidges(int i, int j, float zoom, float factor, Vector2 seed)
{
i = i + Mathf.RoundToInt(seed.x * zoom);
j = j + Mathf.RoundToInt(seed.y * zoom);
//fractal behavior occurs here. Everything else is parameter fine-tuning
float sum = 0
+ Mathf.PerlinNoise(i / zoom, j / zoom) / 3
+ Mathf.PerlinNoise(i / (zoom / factor), j / (zoom / factor)) / 3
+ Mathf.PerlinNoise(i / (zoom / factor * factor), j / (zoom / factor * factor)) / 3;
return 1 - Mathf.Abs(sum - 0.5f)*2f;
}
float FractalNoiseMounds(int i, int j, float zoom, float factor, Vector2 seed)
{
i = i + Mathf.RoundToInt(seed.x * zoom);
j = j + Mathf.RoundToInt(seed.y * zoom);
//fractal behavior occurs here. Everything else is parameter fine-tuning
float sum = 0
+ Mathf.PerlinNoise(i / zoom, j / zoom) / 3
+ Mathf.PerlinNoise(i / (zoom / factor), j / (zoom / factor)) / 3
+ Mathf.PerlinNoise(i / (zoom / factor * factor), j / (zoom / factor * factor)) / 3;
return Mathf.Abs(sum - 0.5f) * 2f;
}
//makes and calculates the values of the 3 arrays that are used to determine the type of tile
void MakeArrays()
{
he_array = new float[x, y];
hu_array = new float[x, y];
te_array = new float[x, y];
RecalculateArray();
}
void RecalculateArray()
{
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
he_array[i, j] = height_multiplier.Evaluate(FractalNoise(i, j, he_zoom, he_factor, he_seed));
hu_array[i, j] = FractalNoise(i, j, hu_zoom, hu_factor, hu_seed)+ humidity_plus;
te_array[i, j] = FractalNoise(i, j, tmp_zoom, tmp_factor, tmp_seed);
}
}
}
void MakeTiles()
{
tiles = new Transform[x, y];
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
tiles[i, j] = Instantiate(tile, new Vector2(i, j), Quaternion.identity, parent);
}
}
PaintTiles();
}
//colors all tiles based on the values of the arrays
void PaintTiles()
{
Random.InitState(35);
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
switch (col_type)
{
case "g":
tiles[i, j].GetComponent<Renderer>().material.color = ColorGradient(i, j);
break;
case "l":
tiles[i, j].GetComponent<Renderer>().material.color = ColorLimit(i, j);
break;
case "r":
tiles[i, j].GetComponent<Renderer>().material.color = ColorChance(i, j);
break;
default:
tiles[i, j].GetComponent<Renderer>().material.color = ColorGradient(i, j);
break;
}
}
}
}
void Clean()
{
he_array = new float[0, 0];
hu_array = new float[0, 0];
te_array = new float[0, 0];
foreach (Transform item in tiles)
{
//not sure how safe this is. So far it works, even if it irks.
Destroy(item.gameObject);
}
}
//returns a tile color based on the values of the arrays.
Color ColorGradient(int i, int j)
{
Color greenery = Color.Lerp(Desert, Forest, hu_array[i, j]);
Color height = Color.Lerp(greenery, Peak, he_array[i, j]);
Color final;
if (he_array[i, j] <= water_percent)
{
final = Sea;
}
else
{
final = height;
}
return final;
}
Color ColorLimit(int i, int j)
{
if (he_array[i, j] <= water_percent)
{
return Sea;
}
if (he_array[i, j] >= mountain_threshold)
{
return Peak;
}
if (hu_array[i, j] >= 0.6)
{
return Forest;
}
if (hu_array[i, j] <= 0.3)
{
return Desert;
}
return Plains;
}
Color ColorChance(int i, int j)
{
if (he_array[i, j] <= water_percent)
{
return Sea;
}
if (he_array[i, j] >= mountain_threshold + Random.Range(0f, 1- mountain_threshold))
{
return Peak;
}
if (hu_array[i, j] >= 0.5f + Random.Range(0f, 0.5f))
{
return Forest;
}
if (hu_array[i, j] <= 0.3f - Random.Range(0f, 0.3f))
{
return Desert;
}
return Plains;
}