Newer
Older
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public float amplitude;
public float frequency;
}
[System.Serializable]
public enum NoiseType
{
MathfPerlin,
MathematicsPerlin,
public class TerrainGenThread
{
private Vector2 initialCrawlPosition;
private List<Octave> octaves;
private int xSamples, ySamples;
public TerrainGenThread(Vector2 initialCrawlPos, List<Octave> octaves, int xSamples, int ySamples, out TerrainData data)
this.octaves = octaves;
this.xSamples = xSamples;
this.ySamples = ySamples;
data = new();
data.size = new(512, 512, 512);
terrainData = data;
}
public float[,] GetHeights()
{
if (ready)
return heights;
else
throw new System.InvalidOperationException("Heights not built yet.");
}
heights = new float[xSamples, ySamples];
foreach (var octave in octaves)
{
for (int x = 0; x < xSamples; x++)
{
for (int y = 0; y < ySamples; y++)
{
float2 crawlPos = new(x * octave.frequency + initialCrawlPosition.x, y * octave.frequency + initialCrawlPosition.y);
float addition;
switch (octave.type)
{
default:
case NoiseType.MathfPerlin:
addition = Mathf.PerlinNoise(crawlPos.x, crawlPos.y);
break;
case NoiseType.MathematicsPerlin:
addition = noise.cnoise(crawlPos) / 2.3f + 0.5f;
break;
case NoiseType.Simplex:
addition = noise.snoise(crawlPos) / 4.6f + 0.5f;
break;
case NoiseType.Celluar:
addition = noise.cellular(crawlPos).x / 2.3f + 0.5f;
break;
}
heights[x, y] += addition * octave.amplitude;
}
}
}
ready = true;
//terrainData.SetHeights(0, 0, heights);
//GameObject obj = Terrain.CreateTerrainGameObject(terrainData);
//obj.name = initialCrawlPosition.ToString() + "Terrain";
[Tooltip("The seed of the generation.")]
public Vector2 crawlStartPosition;
public bool generateNewSeed = true;
//[Tooltip("How many terrain elements are there?")]
//public Vector2Int terrainsSize = new(1,1);
[Tooltip("How fine grain the generated terrain will be. " +
"Larger values = more precise. Recommended value is 513.")]
public int xSamples = 513, ySamples = 513;
[Header("Autogenerated values")]
[Tooltip("Which terrain grid are we on right now?")]
public Vector2Int currentGridPosition;
[Tooltip("Dictionary of previously loaded terrains.")]
public Dictionary<Vector2Int, TerrainData> previouslyLoaded = new();
/// <summary>
/// 4 threads for each cardinal direction. Responsible for creating
/// their respective terrains in each cardinal direction.
/// </summary>
private Thread northThread, eastThread, southThread, westThread;
private void GenerateThread(Vector2 crawlPos, Vector2Int gridPos, ref Thread thread)
TerrainGenThread genThread = new(crawlPos, octaves, xSamples, ySamples, out TerrainData data);
thread = new Thread(new ThreadStart(genThread.Generate));
previouslyLoaded[gridPos] = data;
thread.Start();
thread.Join();
data.SetHeights(0, 0, genThread.GetHeights());
GameObject obj = Terrain.CreateTerrainGameObject(data);
obj.name = crawlPos.ToString() + "Terrain";
}
public virtual void GenerateSurronding(Vector2 initCrawlPos)
{
GenerateThread(initCrawlPos + Vector2.up * ySamples,
currentGridPosition + Vector2Int.up, ref northThread);
//GenerateThread(initCrawlPos + Vector2.down * ySamples,
// currentGridPosition + Vector2Int.down, ref southThread);
//GenerateThread(initCrawlPos + Vector2.right * xSamples,
// currentGridPosition + Vector2Int.right, ref eastThread);
//GenerateThread(initCrawlPos + Vector2.left * xSamples,
// currentGridPosition + Vector2Int.left, ref westThread);
//terrainData.SetHeights(0, 0, heights);
//GameObject obj = Terrain.CreateTerrainGameObject(terrainData);
//obj.name = initialCrawlPosition.ToString() + "Terrain";
float[,] heights = new float[xSamples, ySamples];
if (generateNewSeed)
{
crawlStartPosition = RNG.GetRandomVector2(-xSamples, -ySamples, xSamples, ySamples);
foreach (var octave in octaves)
{
for (int x = 0; x < xSamples; x++)
{
for (int y = 0; y < ySamples; y++)
{
float2 crawlPos = new(x * octave.frequency + crawlStartPosition.x, y * octave.frequency + crawlStartPosition.y);
float addition;
switch (octave.type)
{
default:
case NoiseType.MathfPerlin:
addition = Mathf.PerlinNoise(crawlPos.x, crawlPos.y);
break;
case NoiseType.MathematicsPerlin:
addition = noise.cnoise(crawlPos) / 2.3f + 0.5f;
break;
case NoiseType.Simplex:
addition = noise.snoise(crawlPos) / 4.6f + 0.5f;
break;
case NoiseType.Celluar:
addition = noise.cellular(crawlPos).x / 2.3f + 0.5f;
break;
}
heights[x, y] += addition * octave.amplitude;
}
}
}
terrain.terrainData.SetHeights(0, 0, heights);
}
//Generate();
GenerateSurronding(new Vector2(0, 0));
//if (refresh)
//{
// refresh = false;
// Generate();
//}