Newer
Older
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public float amplitude;
public float frequency;
}
[System.Serializable]
public enum NoiseType
{
MathfPerlin,
MathematicsPerlin,
[Tooltip("The seed of the generation.")]
public Vector2 crawlStartPosition;
public bool generateNewSeed = true;
[Tooltip("How fine grain the generated terrain will be. " +
"Larger values = more precise. Recommended value is 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();
/// Threads used for generating the neighboring and current terrains.
private List<TerrainGenJob> generatorJobs = new();
private List<JobHandle> generatorHandles = new();
private void ThreadGenerationFinished(TerrainGenThread genThread)
genThread.TerrainData.SetHeights(0, 0, genThread.GetHeights());
GameObject obj = Terrain.CreateTerrainGameObject(genThread.TerrainData);
obj.name = genThread.InitialCrawlPosition.ToString() + "Terrain";
obj.transform.SetParent(transform, false);
Vector3 offset = new Vector3(genThread.GridPosition.x, 0, genThread.GridPosition.y) *
genThread.TerrainData.size.x;
obj.transform.position += offset;
}
private void ThreadGenerationFinished(TerrainGenJob genJob)
{
TerrainData data = Instantiate(Resources.Load<TerrainData>("Template"));
data.SetHeights(0, 0, genJob.GetHeights());
GameObject obj = Terrain.CreateTerrainGameObject(data);
obj.name = genJob.InitialCrawlPosition.ToString() + "Terrain";
obj.transform.SetParent(transform, false);
Vector3 offset = new Vector3(genJob.GridPosition.x, 0, genJob.GridPosition.y) *
data.size.x;
obj.transform.position += offset;
}
private void GenerateThread(Vector2 crawlPos, Vector2Int gridPos, ref Thread thread,
ref List<TerrainGenThread> genThreads, bool forceRefresh)
{
if (!previouslyLoaded.ContainsKey(gridPos) || forceRefresh)
TerrainData data = Instantiate(Resources.Load<TerrainData>("Template"));
TerrainGenThread genThread = new(crawlPos, gridPos, octaves, samples, data);
genThreads.Add(genThread);
private void GenerateThread(Vector2 crawlPos, Vector2Int gridPos, NativeArray<Octave> octaves,
ref List<TerrainGenJob> genJobs, ref List<JobHandle> handles, bool forceRefresh)
{
if (!previouslyLoaded.ContainsKey(gridPos) || forceRefresh)
{
TerrainGenJob genJob = new(crawlPos, gridPos, octaves, samples);
genJobs.Add(genJob);
JobHandle jobHandle = genJob.Schedule();
handles.Add(jobHandle);
}
}
private NativeArray<Octave> nOctaves;
public virtual void GenerateSurronding(Vector2 initCrawlPos, bool forceRefresh = false)
nOctaves = new(octaves.ToArray(), Allocator.Persistent);
for (int i = -1; i <= 1; i++)
{
for (int j = 1; j >= -1; j--)
{
//GenerateThread(initCrawlPos + new Vector2(i, j),
// currentGridPosition + new Vector2Int(i, j),
// ref generationThreads[count], ref generators,
// forceRefresh);
GenerateThread(initCrawlPos + new Vector2(i, j),
currentGridPosition + new Vector2Int(i, j),
nOctaves,
ref generatorJobs, ref generatorHandles,
StartCoroutine(JoinThreads(10f));
}
private IEnumerator JoinThreads(float time)
{
yield return new WaitForSecondsRealtime(time);
// Code to ensure jobs are finished. This should optimally occur
// sometime after.
StartCoroutine(JoinOnGeneratorThreads(0.1f));
}
private IEnumerator JoinOnGeneratorThreads(float timeToWait)
{
yield return new WaitForSecondsRealtime(timeToWait);
//foreach (var thread in generationThreads)
//{
// if (thread != null)
// {
// thread.Join();
// }
//}
//foreach (var genThread in generators)
//{
// if (genThread != null)
// {
// ThreadGenerationFinished(genThread);
// }
//}
//generators.Clear();
foreach (var handle in generatorHandles)
foreach (var job in generatorJobs)
{
ThreadGenerationFinished(job);
}
generatorJobs.Clear();
generatorHandles.Clear();
nOctaves.Dispose();
if (refresh)
{
refresh = false;
foreach (Transform child in transform)
Destroy(child.gameObject);
GenerateSurronding(crawlStartPosition, true);
}
private void OnDestroy()
{
nOctaves.Dispose();
}