The virtual terrain, (assuming you talking the noise generator) is limited to be between int.minvalue and int.maxvalue, each chunk only increase/decrease the area by 1 about the code, the only 2 script that is active doing generation is these, don’t mind the mess from the debugging…
Chunkloader:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ChunkLoader : MonoBehaviour
{
public static ChunkLoader chunkloader;
int LoadDistance = 9;
int Center { get { return (LoadDistance - 1) / 2; } }
int ChunkSize;
public List<List<GameObject>> Chunks = new List<List<GameObject>>();
Terrain lt;
Terrain rt;
Terrain tt;
Terrain bt;
[SerializeField]
GameObject Player;
public ChunkLoader()
{
chunkloader = this;
}
// Use this for initialization
void Start ()
{
ChunkSize = DataBaseHandler.ChunkSize;
for (int i = 0; i < LoadDistance; i++)
{
List<GameObject> lgo = new List<GameObject>();
for (int j = 0; j < LoadDistance; j++)
{
GameObject go = new GameObject();
go.AddComponent<Chunk>();
go.transform.position = new Vector3(((((LoadDistance - 1) / 2) - LoadDistance) + j + 1) * ChunkSize, 0, (((LoadDistance - 1) / 2 - LoadDistance) + i + 1) * ChunkSize);
go.name = "Chunk" + "[" + (j - Center) + ";" + (i - Center) + "]";
lgo.Add(go);
go.GetComponent<Chunk>().Generate();
}
Chunks.Add(lgo);
}
for (int i = 0; i < LoadDistance; i++)
{
for (int j = 0; j < LoadDistance; j++)
{
if (i != 0)
{
bt = Chunks[i - 1][j].GetComponent<Terrain>();
TerrainStitcher.stitch(bt, Chunks[i][j].GetComponent<Terrain>(), 16, 0);
}
if (i != LoadDistance - 1)
{
tt = Chunks[i + 1][j].GetComponent<Terrain>();
TerrainStitcher.stitch(tt, Chunks[i][j].GetComponent<Terrain>(), 16, 0);
}
if (j != 0)
{
lt = Chunks[i][j - 1].GetComponent<Terrain>();
TerrainStitcher.stitch(lt, Chunks[i][j].GetComponent<Terrain>(), 16, 0);
}
if (j != LoadDistance - 1)
{
rt = Chunks[i][j + 1].GetComponent<Terrain>();
TerrainStitcher.stitch(rt, Chunks[i][j].GetComponent<Terrain>(), 16, 0);
}
Chunks[i][j].GetComponent<Terrain>().SetNeighbors(lt, tt, rt, bt);
Chunks[i][j].GetComponent<Terrain>().Flush();
bt = null;
tt = null;
lt = null;
rt = null;
}
}
}
// Update is called once per frame
void Update()
{
if (Player.transform.position.z < Chunks[Center - 1][Center].transform.position.z + (ChunkSize / 2))
{
AddColumnBack();
DeleteColumnFront();
}
if (Player.transform.position.z > Chunks[Center + 1][Center].transform.position.z + (ChunkSize / 2))
{
AddColumnFront();
DeleteColumnBack();
}
if (Player.transform.position.x < Chunks[Center][Center - 1].transform.position.x + (ChunkSize / 2))
{
AddRowBack();
DeleteRowFront();
}
if (Player.transform.position.x > Chunks[Center][Center + 1].transform.position.x + (ChunkSize / 2))
{
AddRowFront();
DeleteRowBack();
}
}
void AddColumnFront()
{
Vector3 vec = Chunks[Chunks.Count - 1][Center].transform.position;
List<GameObject> lgo = new List<GameObject>();
int c = -(Center * ChunkSize);
for (int i = 0; i < Chunks.Count; i++)
{
GameObject go = new GameObject();
go.transform.position = new Vector3(vec.x + c, 0, vec.z + ChunkSize);
go.AddComponent<Chunk>();
go.name = "Chunk" + "[" + go.transform.position.x / ChunkSize + ";" + go.transform.position.z / ChunkSize + "]";
lgo.Add(go);
go.GetComponent<Chunk>().Generate();
c += ChunkSize;
}
Chunks.Add(lgo);
for (int i = 0; i < Chunks.Count - 1; i++)
{
if (i == 0)
{
TerrainTools.StitchTerrains(Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), Chunks[Chunks.Count - 1][i + 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), Chunks[Chunks.Count - 2][i].GetComponent<Terrain>(), 16, 0);
Chunks[Chunks.Count - 1][i].GetComponent<Terrain>().SetNeighbors(null, null, Chunks[Chunks.Count - 1][i + 1].GetComponent<Terrain>(), Chunks[Chunks.Count - 2][i].GetComponent<Terrain>());
Chunks[Chunks.Count - 1][i].GetComponent<Terrain>().Flush();
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().SetNeighbors(null, Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), Chunks[Chunks.Count - 2][i + 1].GetComponent<Terrain>(), Chunks[Chunks.Count - 3][i].GetComponent<Terrain>());
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().Flush();
}
else if (i == Chunks.Count - 2)
{
TerrainTools.StitchTerrains(Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), Chunks[Chunks.Count - 1][i - 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), Chunks[Chunks.Count - 2][i].GetComponent<Terrain>(), 16, 0);
Chunks[Chunks.Count - 1][i].GetComponent<Terrain>().SetNeighbors(Chunks[Chunks.Count - 1][i - 1].GetComponent<Terrain>(), null, null, Chunks[Chunks.Count - 2][i].GetComponent<Terrain>());
Chunks[Chunks.Count - 1][i].GetComponent<Terrain>().Flush();
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().SetNeighbors(Chunks[Chunks.Count - 2][i - 1].GetComponent<Terrain>(), Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), null, Chunks[Chunks.Count - 3][i].GetComponent<Terrain>());
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().Flush();
}
else
{
TerrainTools.StitchTerrains(Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), Chunks[Chunks.Count - 1][i - 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), Chunks[Chunks.Count - 1][i + 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), Chunks[Chunks.Count - 2][i].GetComponent<Terrain>(), 16, 0);
Chunks[Chunks.Count - 1][i].GetComponent<Terrain>().SetNeighbors(Chunks[Chunks.Count - 1][i - 1].GetComponent<Terrain>(), null, Chunks[Chunks.Count - 1][i + 1].GetComponent<Terrain>(), Chunks[Chunks.Count - 2][i].GetComponent<Terrain>());
Chunks[Chunks.Count - 1][i].GetComponent<Terrain>().Flush();
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().SetNeighbors(Chunks[Chunks.Count - 2][i - 1].GetComponent<Terrain>(), Chunks[Chunks.Count - 1][i].GetComponent<Terrain>(), Chunks[Chunks.Count - 2][i + 1].GetComponent<Terrain>(), Chunks[Chunks.Count - 3][i].GetComponent<Terrain>());
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().Flush();
}
}
}
void AddColumnBack()
{
Vector3 vec = Chunks[0][Center].transform.position;
List<GameObject> lgo = new List<GameObject>();
int c = -(Center * ChunkSize);
for (int i = 0; i < Chunks.Count; i++)
{
GameObject go = new GameObject();
go.transform.position = new Vector3(vec.x + c, 0, vec.z - ChunkSize);
go.AddComponent<Chunk>();
go.name = "Chunk" + "[" + go.transform.position.x / ChunkSize + ";" + go.transform.position.z / ChunkSize + "]";
lgo.Add(go);
go.GetComponent<Chunk>().Generate();
c += ChunkSize;
}
Chunks.Insert(0, lgo);
for (int i = 0; i < Chunks.Count - 1; i++)
{
if (i == 0)
{
TerrainTools.StitchTerrains(Chunks[0][i].GetComponent<Terrain>(), Chunks[0][i + 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[0][i].GetComponent<Terrain>(), Chunks[1][i].GetComponent<Terrain>(), 16, 0);
Chunks[0][i].GetComponent<Terrain>().SetNeighbors(null, Chunks[1][i].GetComponent<Terrain>(), Chunks[0][i + 1].GetComponent<Terrain>(), null);
Chunks[0][i].GetComponent<Terrain>().Flush();
Chunks[1][i].GetComponent<Terrain>().SetNeighbors(null, Chunks[2][i].GetComponent<Terrain>(), Chunks[1][i + 1].GetComponent<Terrain>(), Chunks[0][i].GetComponent<Terrain>());
Chunks[1][i].GetComponent<Terrain>().Flush();
}
else if (i == Chunks.Count - 2)
{
TerrainTools.StitchTerrains(Chunks[0][i].GetComponent<Terrain>(), Chunks[0][i - 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[0][i].GetComponent<Terrain>(), Chunks[1][i].GetComponent<Terrain>(), 16, 0);
Chunks[0][i].GetComponent<Terrain>().SetNeighbors(Chunks[0][i - 1].GetComponent<Terrain>(), Chunks[1][i].GetComponent<Terrain>(), null, null);
Chunks[0][i].GetComponent<Terrain>().Flush();
Chunks[1][i].GetComponent<Terrain>().SetNeighbors(Chunks[1][i - 1].GetComponent<Terrain>(), Chunks[2][i].GetComponent<Terrain>(), null, Chunks[0][i].GetComponent<Terrain>());
Chunks[1][i].GetComponent<Terrain>().Flush();
}
else
{
TerrainTools.StitchTerrains(Chunks[0][i].GetComponent<Terrain>(), Chunks[0][i - 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[0][i].GetComponent<Terrain>(), Chunks[0][i + 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[0][i].GetComponent<Terrain>(), Chunks[1][i].GetComponent<Terrain>(), 16, 0);
Chunks[0][i].GetComponent<Terrain>().SetNeighbors(Chunks[0][i - 1].GetComponent<Terrain>(), Chunks[1][i].GetComponent<Terrain>(), Chunks[0][i + 1].GetComponent<Terrain>(), null);
Chunks[0][i].GetComponent<Terrain>().Flush();
Chunks[1][i].GetComponent<Terrain>().SetNeighbors(Chunks[1][i - 1].GetComponent<Terrain>(), Chunks[2][i].GetComponent<Terrain>(), Chunks[1][i + 1].GetComponent<Terrain>(), Chunks[0][i].GetComponent<Terrain>());
Chunks[1][i].GetComponent<Terrain>().Flush();
}
}
}
void AddRowFront()
{
Vector3 vec = Chunks[Center][Chunks[1].Count - 1].transform.position;
int c = -(Center * ChunkSize);
foreach (List<GameObject> lgo in Chunks)
{
GameObject go = new GameObject();
go.transform.position = new Vector3(vec.x + ChunkSize, 0, vec.z + c);
go.AddComponent<Chunk>();
go.name = "Chunk" + "[" + go.transform.position.x / ChunkSize + ";" + go.transform.position.z / ChunkSize + "]";
go.GetComponent<Chunk>().Generate();
lgo.Add(go);
c += ChunkSize;
}
for (int i = 0; i < Chunks.Count; i++)
{
if (i == 0)
{
TerrainTools.StitchTerrains(Chunks[i][Chunks.Count].GetComponent<Terrain>(), Chunks[i][Chunks.Count - 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[i][Chunks.Count].GetComponent<Terrain>(), Chunks[i + 1][Chunks.Count].GetComponent<Terrain>(), 16, 0);
Chunks[i][Chunks.Count].GetComponent<Terrain>().SetNeighbors(Chunks[i][Chunks.Count - 1].GetComponent<Terrain>(), Chunks[i + 1][Chunks.Count].GetComponent<Terrain>(), null, null);
Chunks[i][Chunks.Count].GetComponent<Terrain>().Flush();
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().SetNeighbors(Chunks[i][Chunks.Count - 2].GetComponent<Terrain>(), Chunks[i + 1][Chunks.Count - 1].GetComponent<Terrain>(), Chunks[i][Chunks.Count].GetComponent<Terrain>(), null);
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().Flush();
}
else if (i == Chunks.Count - 1)
{
TerrainTools.StitchTerrains(Chunks[i][Chunks.Count].GetComponent<Terrain>(), Chunks[i][Chunks.Count - 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[i][Chunks.Count].GetComponent<Terrain>(), Chunks[i - 1][Chunks.Count].GetComponent<Terrain>(), 16, 0);
Chunks[i][Chunks.Count].GetComponent<Terrain>().SetNeighbors(Chunks[i][Chunks.Count - 1].GetComponent<Terrain>(), null, null, Chunks[i - 1][Chunks.Count].GetComponent<Terrain>());
Chunks[i][Chunks.Count].GetComponent<Terrain>().Flush();
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().SetNeighbors(Chunks[i][Chunks.Count - 2].GetComponent<Terrain>(), null, Chunks[i][Chunks.Count].GetComponent<Terrain>(), Chunks[i - 1][Chunks.Count - 1].GetComponent<Terrain>());
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().Flush();
}
else
{
TerrainTools.StitchTerrains(Chunks[i][Chunks.Count].GetComponent<Terrain>(), Chunks[i][Chunks.Count - 1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[i][Chunks.Count].GetComponent<Terrain>(), Chunks[i - 1][Chunks.Count].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[i][Chunks.Count].GetComponent<Terrain>(), Chunks[i + 1][Chunks.Count].GetComponent<Terrain>(), 16, 0);
Chunks[i][Chunks.Count].GetComponent<Terrain>().SetNeighbors(Chunks[i][Chunks.Count - 1].GetComponent<Terrain>(), Chunks[i + 1][Chunks.Count].GetComponent<Terrain>(), null, Chunks[i - 1][Chunks.Count].GetComponent<Terrain>());
Chunks[i][Chunks.Count].GetComponent<Terrain>().Flush();
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().SetNeighbors(Chunks[i][Chunks.Count - 2].GetComponent<Terrain>(), Chunks[i + 1][Chunks.Count - 1].GetComponent<Terrain>(), Chunks[i][Chunks.Count].GetComponent<Terrain>(), Chunks[i - 1][Chunks.Count - 1].GetComponent<Terrain>());
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().Flush();
}
}
}
void AddRowBack()
{
Vector3 vec = Chunks[Center][0].transform.position;
int c = -(Center * ChunkSize);
foreach (List<GameObject> lgo in Chunks)
{
GameObject go = new GameObject();
go.transform.position = new Vector3(vec.x - ChunkSize, 0, vec.z + c);
go.AddComponent<Chunk>();
go.name = "Chunk" + "[" + go.transform.position.x / ChunkSize + ";" + go.transform.position.z / ChunkSize + "]";
go.GetComponent<Chunk>().Generate();
lgo.Insert(0, go);
c += ChunkSize;
}
for (int i = 0; i < Chunks.Count; i++)
{
if (i == 0)
{
TerrainTools.StitchTerrains(Chunks[i][0].GetComponent<Terrain>(), Chunks[i][1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[i][0].GetComponent<Terrain>(), Chunks[i + 1][0].GetComponent<Terrain>(), 16, 0);
Chunks[i][0].GetComponent<Terrain>().SetNeighbors(null, Chunks[i + 1][0].GetComponent<Terrain>(), Chunks[i][1].GetComponent<Terrain>(), null);
Chunks[i][0].GetComponent<Terrain>().Flush();
Chunks[i][1].GetComponent<Terrain>().SetNeighbors(Chunks[i][0].GetComponent<Terrain>(), Chunks[i + 1][1].GetComponent<Terrain>(), Chunks[i][2].GetComponent<Terrain>(), null);
Chunks[i][1].GetComponent<Terrain>().Flush();
}
else if (i == Chunks.Count - 1)
{
TerrainTools.StitchTerrains(Chunks[i][0].GetComponent<Terrain>(), Chunks[i][1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[i][0].GetComponent<Terrain>(), Chunks[i - 1][0].GetComponent<Terrain>(), 16, 0);
Chunks[i][0].GetComponent<Terrain>().SetNeighbors(null, null, Chunks[i][1].GetComponent<Terrain>(), Chunks[i - 1][0].GetComponent<Terrain>());
Chunks[i][0].GetComponent<Terrain>().Flush();
Chunks[i][1].GetComponent<Terrain>().SetNeighbors(Chunks[i][0].GetComponent<Terrain>(), null, Chunks[i][2].GetComponent<Terrain>(), Chunks[i - 1][1].GetComponent<Terrain>());
Chunks[i][1].GetComponent<Terrain>().Flush();
}
else
{
TerrainTools.StitchTerrains(Chunks[i][0].GetComponent<Terrain>(), Chunks[i][1].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[i][0].GetComponent<Terrain>(), Chunks[i - 1][0].GetComponent<Terrain>(), 16, 0);
TerrainTools.StitchTerrains(Chunks[i][0].GetComponent<Terrain>(), Chunks[i + 1][0].GetComponent<Terrain>(), 16, 0);
Chunks[i][0].GetComponent<Terrain>().SetNeighbors(null, Chunks[i + 1][0].GetComponent<Terrain>(), Chunks[i][1].GetComponent<Terrain>(), Chunks[i - 1][0].GetComponent<Terrain>());
Chunks[i][0].GetComponent<Terrain>().Flush();
Chunks[i][1].GetComponent<Terrain>().SetNeighbors(Chunks[i][0].GetComponent<Terrain>(), Chunks[i + 1][1].GetComponent<Terrain>(), Chunks[i][2].GetComponent<Terrain>(), Chunks[i - 1][1].GetComponent<Terrain>());
Chunks[i][1].GetComponent<Terrain>().Flush();
}
}
}
void DeleteColumnFront()
{
for (int i = 0; i < Chunks[Chunks.Count - 1].Count; i++)
{
if (i == 0)
{
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().SetNeighbors(null, null, Chunks[Chunks.Count - 2][i + 1].GetComponent<Terrain>(), Chunks[Chunks.Count - 3][i].GetComponent<Terrain>());
}
else if (i == Chunks[0].Count - 1)
{
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().SetNeighbors(Chunks[Chunks.Count - 2][i - 1].GetComponent<Terrain>(), null, null, Chunks[Chunks.Count - 3][i].GetComponent<Terrain>());
}
else
{
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().SetNeighbors(Chunks[Chunks.Count - 2][i - 1].GetComponent<Terrain>(), null, Chunks[Chunks.Count - 2][i + 1].GetComponent<Terrain>(), Chunks[Chunks.Count - 3][i].GetComponent<Terrain>());
}
Chunks[Chunks.Count - 2][i].GetComponent<Terrain>().Flush();
GameObject.Destroy(Chunks[Chunks.Count - 1][i]);
}
Chunks.RemoveAt(Chunks.Count - 1);
}
void DeleteColumnBack()
{
for (int i = 0; i < Chunks[0].Count; i++)
{
if (i == 0)
{
Chunks[1][i].GetComponent<Terrain>().SetNeighbors(null, Chunks[2][i].GetComponent<Terrain>(), Chunks[1][i + 1].GetComponent<Terrain>(), null);
}
else if (i == Chunks[0].Count - 1)
{
Chunks[1][i].GetComponent<Terrain>().SetNeighbors(Chunks[1][i - 1].GetComponent<Terrain>(), Chunks[2][i].GetComponent<Terrain>(), null, null);
}
else
{
Chunks[1][i].GetComponent<Terrain>().SetNeighbors(Chunks[1][i - 1].GetComponent<Terrain>(), Chunks[2][i].GetComponent<Terrain>(), Chunks[1][i + 1].GetComponent<Terrain>(), null);
}
Chunks[1][i].GetComponent<Terrain>().Flush();
GameObject.Destroy(Chunks[0][i]);
}
Chunks.RemoveAt(0);
}
void DeleteRowFront()
{
for (int i = 0; i < Chunks.Count; i++)
{
if (i == 0)
{
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().SetNeighbors(Chunks[i][Chunks.Count - 2].GetComponent<Terrain>(), Chunks[i + 1][Chunks.Count - 1].GetComponent<Terrain>(), null, null);
}
else if (i == Chunks.Count - 1)
{
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().SetNeighbors(Chunks[i][Chunks.Count - 2].GetComponent<Terrain>(), null, null, Chunks[i - 1][Chunks.Count - 1].GetComponent<Terrain>());
}
else
{
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().SetNeighbors(Chunks[i][Chunks.Count - 2].GetComponent<Terrain>(), Chunks[i + 1][Chunks.Count - 1].GetComponent<Terrain>(), null, Chunks[i - 1][Chunks.Count - 1].GetComponent<Terrain>());
}
Chunks[i][Chunks.Count - 1].GetComponent<Terrain>().Flush();
}
for (int i = 0; i < Chunks.Count; i++)
{
GameObject.Destroy(Chunks[i][Chunks.Count]);
Chunks[i].RemoveAt(Chunks.Count);
}
}
void DeleteRowBack()
{
for (int i = 0; i < Chunks.Count; i++)
{
if (i == 0)
{
Chunks[i][1].GetComponent<Terrain>().SetNeighbors(null, Chunks[i + 1][1].GetComponent<Terrain>(), Chunks[i][2].GetComponent<Terrain>(), null);
}
else if (i == Chunks.Count - 1)
{
Chunks[i][1].GetComponent<Terrain>().SetNeighbors(null, null, Chunks[i][2].GetComponent<Terrain>(), Chunks[i - 1][1].GetComponent<Terrain>());
}
else
{
Chunks[i][1].GetComponent<Terrain>().SetNeighbors(null, Chunks[i + 1][1].GetComponent<Terrain>(), Chunks[i][2].GetComponent<Terrain>(), Chunks[i - 1][1].GetComponent<Terrain>());
}
Chunks[i][1].GetComponent<Terrain>().Flush();
}
for (int i = 0; i < Chunks.Count; i++)
{
GameObject.Destroy(Chunks[i][0]);
Chunks[i].RemoveAt(0);
}
}
public Chunk GetChunkAtPlayer()
{
return GameObject.Find("Chunk[" + ((int)(Player.transform.position.x / ChunkSize)).ToString() + ";" + ((int)(Player.transform.position.z / ChunkSize)).ToString() + "]").GetComponent<Chunk>();
}
public Chunk GetChunkAtWorldLocation(float x, float y)
{
return GameObject.Find("Chunk[" + ((int)(x / ChunkSize)).ToString() + ";" + ((int)(y / ChunkSize)).ToString() + "]").GetComponent<Chunk>();
}
public Chunk GetChunkAtChunkLocation(int x, int y)
{
return GameObject.Find("Chunk[" + (x).ToString() + ";" + (y).ToString() + "]").GetComponent<Chunk>();
}
}
Chunk:
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;
using LibNoise;
using LibNoise.Operator;
using LibNoise.Generator;
public class Chunk : MonoBehaviour
{
Vector2[,] WindDirection;
float[,] RainShadow;
float[,] Temperature;
float[,] Humidity;
int MaxWindSpeed = 50;
Texture2D rain1;
Texture2D rain2;
NoiseHelper noisehelper;
List<BiomeTypes> availblebiomes = new List<BiomeTypes>();
float xOffset
{
get
{
return this.transform.position.x / ThisTerain.terrainData.size.x;
}
}
float yOffset
{
get
{
return this.transform.position.z / ThisTerain.terrainData.size.x;
}
}
Terrain ThisTerain
{
get
{
return this.gameObject.GetComponent<Terrain>();
}
}
public void Generate()
{
SetupTerainData();
noisehelper = new NoiseHelper(xOffset, yOffset);
BiomeTypes[,] Biomes = GenerateBiomes();
noisehelper.SetBiomes(Biomes);
noisehelper.SetBounds(new Rect(yOffset, yOffset + 1, xOffset, xOffset + 1));
GenerateHeightmap(Biomes);
GenerateAlphamap(Biomes);
ThisTerain.Flush();
}
void SetupTerainData()
{
Terrain terrrain = this.gameObject.AddComponent<Terrain>();
terrrain.terrainData = new TerrainData();
terrrain.terrainData.heightmapResolution = DataBaseHandler.HeighMapSize;
terrrain.terrainData.size = new Vector3(DataBaseHandler.ChunkSize, DataBaseHandler.ChunkSize * 2, DataBaseHandler.ChunkSize);
TerrainCollider terrraincollider = this.gameObject.AddComponent<TerrainCollider>();
terrraincollider.terrainData = terrrain.terrainData;
terrrain.terrainData.alphamapResolution = DataBaseHandler.BiomeMapSize;
terrrain.terrainData.splatPrototypes = DataBaseHandler.DataBase.SplatsPrototypes;
}
void GenerateHeightmap(BiomeTypes[,] biomes)
{
int resolution = ThisTerain.terrainData.heightmapResolution;
float[,] hmap = new float[resolution, resolution];
List <LibNoise.ModuleBase> modules = new List<ModuleBase>();
for (int i = 0; i < availblebiomes.Count; i++)
{
if (!modules.Contains(Biome.FindBiome(availblebiomes[i]).Generate(noisehelper)))
{
modules.Add(Biome.FindBiome(availblebiomes[i]).Generate(noisehelper));
}
}
for (int i = 1; i < modules.Count; i++)
{
if (modules[i] != null)
{
modules[i][0] = modules[i - 1];
}
}
rain1 = new Texture2D(128, 128);
Noise2D heightMap = new Noise2D(resolution, resolution, modules[0]);
heightMap.GeneratePlanar(yOffset, yOffset + 1, xOffset, xOffset + 1);
for (int y = 0; y < resolution; y++)
{
for (int x = 0; x < resolution; x++)
{
hmap[x, y] = (((heightMap[x, y]) * 0.5f) + 0.5f);// (float)((FlatNoiseMap[x, y] * 0.5f) + 0.5f);
}
}
ThisTerain.terrainData.SetHeights(0, 0, hmap);
}
BiomeTypes[,] GenerateBiomes()
{
BiomeTypes[,] biomes = new BiomeTypes[ThisTerain.terrainData.alphamapResolution, ThisTerain.terrainData.alphamapResolution];
int resolution = ThisTerain.terrainData.alphamapResolution;
Noise2D heightMap = new Noise2D(resolution, resolution, new Perlin(0.125, 2, 0.5, 10, 0, QualityMode.High));
heightMap.GeneratePlanar(yOffset, yOffset + 1, xOffset, xOffset + 1);
Noise2D rainfall = new Noise2D(resolution, resolution, new Perlin(0.125, 2, 0.5, 10, 4560, QualityMode.High));
rainfall.GeneratePlanar(yOffset, yOffset + 1, xOffset, xOffset + 1);
Noise2D WindMap = new Noise2D((resolution + (MaxWindSpeed * 2)), (resolution + (MaxWindSpeed * 2)), new Perlin(0.125, 2, 0.5, 10, 0, QualityMode.High));
WindMap.GeneratePlanar(yOffset - ((double)MaxWindSpeed / (double)resolution), (yOffset + 1) + ((double)MaxWindSpeed / (double)resolution), xOffset - ((double)MaxWindSpeed / (double)resolution), (xOffset + 1) + ((double)MaxWindSpeed / (double)resolution));
Noise2D RainCalcMap = new Noise2D((resolution + (MaxWindSpeed * 2)), (resolution + (MaxWindSpeed * 2)), new Perlin(0.125, 2, 0.5, 10, 0, QualityMode.High));
RainCalcMap.GeneratePlanar(xOffset - ((double)MaxWindSpeed / (double)resolution), (xOffset + 1) + ((double)MaxWindSpeed / (double)resolution), yOffset - ((double)MaxWindSpeed / (double)resolution), (yOffset + 1) + ((double)MaxWindSpeed / (double)resolution));
RainShadow = new float[ThisTerain.terrainData.alphamapResolution, ThisTerain.terrainData.alphamapResolution];
Temperature = new float[ThisTerain.terrainData.alphamapResolution, ThisTerain.terrainData.alphamapResolution];
Humidity = new float[ThisTerain.terrainData.alphamapResolution, ThisTerain.terrainData.alphamapResolution];
WindDirection = new Vector2[(resolution + (MaxWindSpeed * 2)), (resolution + (MaxWindSpeed * 2))];
for (int i = 0; i < resolution + (MaxWindSpeed * 2); i++)
{
for (int j = 0; j < resolution + (MaxWindSpeed * 2); j++)
{
float val = ((((CosGradient((i - 50) + (yOffset * (float)(resolution)), (float)(resolution), 0.125f) * 0.5f) + 0.5f) + (((WindMap[i,j]) * 0.5f) + 0.5f) / 2) * 12.0f);
if (val >= 0 && val < 2)
{
if (val >= 1)
{
WindDirection[i, j] = new Vector2(-1.0f, (val - 2.0f));
}
else
{
WindDirection[i, j] = new Vector2(val * -1.0f, -1.0f);
}
}
else if (val >= 2 && val < 4)
{
if (val >= 3)
{
WindDirection[i, j] = new Vector2((4.0f - val), 1.0f);
}
else
{
WindDirection[i, j] = new Vector2(1.0f, val - 2.0f);
}
}
else if (val >= 4 && val < 6)
{
if (val >= 5)
{
WindDirection[i, j] = new Vector2(-1.0f, (val - 6.0f));
}
else
{
WindDirection[i, j] = new Vector2((val - 4.0f) * -1.0f, -1.0f);
}
}
else if (val >= 6 && val < 8)
{
if (val >= 7)
{
WindDirection[i, j] = new Vector2(val - 8.0f, 1.0f);
}
else
{
WindDirection[i, j] = new Vector2(-1.0f, (val - 6.0f));
}
}
else if (val >= 8 && val < 10)
{
if (val >= 9)
{
WindDirection[i, j] = new Vector2(1.0f, (10.0f - val) * -1.0f);
}
else
{
WindDirection[i, j] = new Vector2((val - 8.0f), -1.0f);
}
}
else if (val >= 10 && val <= 12)
{
if (val >= 11)
{
WindDirection[i, j] = new Vector2((val - 12.0f), 1.0f);
}
else
{
WindDirection[i, j] = new Vector2(-1.0f, (val - 10.0f));
}
}
}
}
for (int i = -MaxWindSpeed; i < RainCalcMap.Width - MaxWindSpeed; i++)
{
for (int j = -MaxWindSpeed; j < RainCalcMap.Height - MaxWindSpeed; j++)
{
if (RainCalcMap[i + MaxWindSpeed, j + MaxWindSpeed] <= 0.5f)
{
Bresenham(i, i + (int)(WindDirection[j + MaxWindSpeed, i + MaxWindSpeed].x * MaxWindSpeed), j, j + (int)(WindDirection[j + MaxWindSpeed, i + MaxWindSpeed].y * MaxWindSpeed));
}
}
}
//TODO: Remove the rain1 and rain2 textures from the game!
//Smoothen(ref RainShadow);
for (int i = 0; i < ThisTerain.terrainData.alphamapResolution; i++)
{
for (int j = 0; j < ThisTerain.terrainData.alphamapResolution; j++)
{
try
{
Temperature[i, j] = -50.0f + (((((heightMap[i, j] * 0.5f) + 0.5f) + (CosGradient(i + (yOffset * (float)(resolution)), (float)(resolution), 0.25f) * 0.5f) + 0.5f) / 2.0f) * 100.0f);
//Humidity[i, j] = ((((CosGradient(i + (yOffset * (float)(resolution)), (float)(resolution), 0.25f) * 0.5f) + 0.5f)) * 100.0f) * (((rainfall[i, j] * 0.5f) + 0.5f));
Humidity[i, j] = ((((rainfall[i, j] * 0.5f) + 0.5f)) * 100.0f);// *(((((heightMap[i, j] * 0.75f) + 0.5f) + (CosGradient(i + (yOffset * (float)(resolution)), (float)(resolution), 0.5f) * 0.25f) + 0.5f) / 2.0f));
//Old Biome Selector
//biomes[i, j] = DataBaseHandler.DataBase.BiomeDiagram[Mathf.RoundToInt((((heightMap[i, j] * 0.5f) + 0.5f) + (CosGradient(i + (yOffset * (float)(resolution)), (float)(resolution), 0.5f) * 0.5f) + 0.5f) / 2), Mathf.RoundToInt((RainShadow[i, j] + ((rainfall[i, j] * 0.5f) + 0.5f) / 2) * 2)];
biomes[i, j] = Biome.DecideBiome(Temperature[i, j], Humidity[i, j]);
if (!availblebiomes.Contains(biomes[i, j]))
{
availblebiomes.Add(biomes[i, j]);
}
}
catch(Exception ex)
{
}
}
}
return biomes;
}
void Bresenham(int x0, int x1, int y0, int y1)
{
//TODO: Add smooth Value curves - ie the value getting smaller and smaller per point it's getting away from the original one.
int sx = 0;
int sy = 0;
int dx = Mathf.Abs(x1 - x0);
int dy = Mathf.Abs(y1 - y0);
if (x0 < x1) { sx = 1; } else { sx = -1; }
if (y0 < y1) { sy = 1; } else { sy = -1; }
int err = dx - dy;
bool loop = true;
while (loop)
{
if ((y0 >= 0 && y0 < RainShadow.GetLength(1)) && (x0 >= 0 && x0 < RainShadow.GetLength(0)))
{
RainShadow[y0, x0] += 0.000004f;
}
if ((x0 == x1) && (y0 == y1)) loop = false;
int e2 = 2 * err;
if (e2 > -dy)
{
err = err - dy;
x0 = x0 + sx;
}
if (e2 < dx)
{
err = err + dx;
y0 = y0 + sy;
}
}
}
//TODO Find a Better smooth algorithm.
public void Smoothen(ref float[,] Heights)
{
int i, j, u, v;
int size = Heights.GetLength(0);
float total;
for (i = 1; i < size - 1; ++i)
{
for (j = 1; j < size - 1; ++j)
{
total = 0.0f;
for (u = -1; u <= 1; u++)
{
for (v = -1; v <= 1; v++)
{
total += Heights[i + u, j + v];
}
}
Heights[i, j] = total / 9.0f;
}
}
}
float CosGradient(float f, float res, float frequency)
{
return ((Mathf.Cos((f / res) * Mathf.PI * frequency)));
}
void GenerateAlphamap(BiomeTypes[,] Biomes)
{
int resolution = ThisTerain.terrainData.alphamapHeight;
float[, ,] amap = new float[ThisTerain.terrainData.alphamapResolution, ThisTerain.terrainData.alphamapResolution, ThisTerain.terrainData.splatPrototypes.Length];
for (int hX = 0; hX < ThisTerain.terrainData.alphamapResolution; hX++)
{
for (int hY = 0; hY < ThisTerain.terrainData.alphamapResolution; hY++)
{
amap[hX, hY, Biome.FindTexture(Biomes[hX, hY])] = 1;
}
}
ThisTerain.terrainData.SetAlphamaps(0, 0, amap);
}
void OnGUI()
{
//if (this.gameObject.name == "Chunk[0;-2]")
//{
GUI.DrawTexture(new Rect((Screen.width / 4) + (128 * xOffset), (Screen.height / 2) - (128 * yOffset), (128), (128)), rain1);
//GUI.DrawTexture(new Rect(128 + 10, 0, 128, 128 + 50), rain2);
//}
}
}