using UnityEngine;
using System;
using System.Threading;
using System.Collections.Generic;
using System.Collections;
public class MapGenerator : MonoBehaviour
{
public enum DrawMode {NoiseMap, ColorMap, Mesh, FalloffMap};
public DrawMode drawMode;
public Noise.NormalizeMode normalizeMode;
const int mapChunkSize = 241;
[Range(0, 6)]
public int levelOfDetail;
public float noiseScale;
[Range(0, 6)]
public int octaves;
[Range(0, 1)]
public float persistance;
public float lacunarity;
public int seed;
public Vector2 offset;
public bool useFalloff;
public float meshHeightMultiplier;
public AnimationCurve meshHeightCurve;
[Range(0, 2)]
[SerializeField]
public float falloffStart;
[Range(0, 2)]
[SerializeField]
public float falloffEnd;
new Vector2Int size = new Vector2Int(mapChunkSize, mapChunkSize);
public bool autoUpdate;
public TerrainType[] regions;
float[,] falloffMap;
void Awake()
{
falloffMap = FalloffGenerator.GenerateFalloffMap(size, falloffStart, falloffEnd);
}
public void GenerateMap()
{
float[,] noiseMap = Noise.GenerateNoiseMap(mapChunkSize, mapChunkSize, seed, noiseScale, octaves, persistance, lacunarity, offset);
MapData mapData = GenerateMapData(Vector2.zero);
Color[] colorMap = new Color[mapChunkSize * mapChunkSize];
for (int y = 0; y < mapChunkSize; y++)
{
for (int x = 0; x < mapChunkSize; x++)
{
float currentHeight = noiseMap[x, y];
for (int i = 0; i < regions.Length; i++)
{
if (currentHeight <= regions[i].height)
{
colorMap[y * mapChunkSize + x] = regions[i].color;
break;
}
}
}
}
MapDisplay display = FindObjectOfType<MapDisplay>();
if (drawMode == DrawMode.NoiseMap)
{
display.DrawTexture(TextureGenerator.TextureFromHeightMap(mapData.heightMap));
}
else if (drawMode == DrawMode.ColorMap)
{
display.DrawTexture(TextureGenerator.TextureFromcolorMap(mapData.colorMap, mapChunkSize, mapChunkSize));
}
else if (drawMode == DrawMode.Mesh)
{
display.DrawMesh(MeshGenerator.GenerateTerrainMesh(mapData.heightMap, meshHeightMultiplier, meshHeightCurve, levelOfDetail), TextureGenerator.TextureFromcolorMap(colorMap, mapChunkSize, mapChunkSize));
}
else if (drawMode == DrawMode.FalloffMap)
{
display.DrawTexture(TextureGenerator.TextureFromHeightMap(FalloffGenerator.GenerateFalloffMap(size, falloffStart, falloffEnd)));
}
}
MapData GenerateMapData(Vector2 centre)
{
float[,] noiseMap = Noise.GenerateNoiseMap(mapChunkSize, mapChunkSize, seed, noiseScale, octaves, persistance, lacunarity, centre + offset);
Color[] colorMap = new Color[mapChunkSize * mapChunkSize];
for (int y = 0; y < mapChunkSize; y++)
{
for (int x = 0; x < mapChunkSize; x++)
{
if (useFalloff)
{
noiseMap[x, y] = Mathf.Clamp01(noiseMap[x, y] - falloffMap[x, y]);
}
float currentHeight = noiseMap[x, y];
for (int i = 0; i < regions.Length; i++)
{
if (currentHeight >= regions[i].height)
{
colorMap[y * mapChunkSize + x] = regions[i].color;
}
else
{
break;
}
}
}
}
return new MapData(noiseMap, colorMap);
}
void OnValidate()
{
if (lacunarity < 1)
{
lacunarity = 1;
}
if (octaves < 0)
{
octaves = 0;
}
}
}
[System.Serializable]
public struct TerrainType
{
public string name;
public float height;
public Color color;
}
public struct MapData
{
public readonly float[,] heightMap;
public readonly Color[] colorMap;
public MapData(float[,] heightMap, Color[] colorMap)
{
this.heightMap = heightMap;
this.colorMap = colorMap;
}
}