100 lines
3.4 KiB
C#
100 lines
3.4 KiB
C#
using System.Linq;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class TerrainGenerator : Manager<TerrainGenerator>
|
|
{
|
|
public int ChunkRadiusX = 1;
|
|
public int ChunkRadiusY = 10;
|
|
public GameObject ChunkPrefab;
|
|
public GameObject TreePrefab;
|
|
public GameObject SnowmanObstaclePrefab;
|
|
|
|
public GameObject PickupPrefab;
|
|
|
|
public AnimationCurve TrenchProfile;
|
|
|
|
private Dictionary<Vector2Int, Chunk> chunks = new Dictionary<Vector2Int, Chunk>();
|
|
|
|
private const int LOAD_PER_UPDATE = 1;
|
|
|
|
public void FixedUpdate()
|
|
{
|
|
HashSet<Vector2Int> loadedPositions = new HashSet<Vector2Int>();
|
|
|
|
for(int x=-ChunkRadiusX;x<=ChunkRadiusX;x++)
|
|
{
|
|
for(int y=-ChunkRadiusY;y<=ChunkRadiusY;y++)
|
|
{
|
|
Vector2Int localChunkPos = new Vector2Int(x, y);
|
|
Vector3 playerGlobalPos = Player.Instance.transform.position;
|
|
Vector2Int playerPos = new Vector2Int((int)(playerGlobalPos.x / Chunk.CHUNK_SIZE), (int)(playerGlobalPos.z / Chunk.CHUNK_SIZE));
|
|
|
|
Vector2Int globalChunkPos = playerPos + localChunkPos;
|
|
loadedPositions.Add(globalChunkPos);
|
|
}
|
|
}
|
|
|
|
List<KeyValuePair<Vector2Int, Chunk>> unload = chunks.Where(x => !loadedPositions.Contains(x.Key)).ToList();
|
|
|
|
foreach(KeyValuePair<Vector2Int, Chunk> instance in unload)
|
|
{
|
|
PoolManager.Instance.ReturnInstance(instance.Value.gameObject);
|
|
chunks.Remove(instance.Key);
|
|
}
|
|
|
|
List<Vector2Int> load = loadedPositions.Where(x => !chunks.ContainsKey(x)).ToList();
|
|
if(GameStateManager.Instance.GameState == GameState.Play)
|
|
load = load.Take(LOAD_PER_UPDATE).ToList();
|
|
foreach(Vector2Int pos in load)
|
|
{
|
|
Chunk c = PoolManager.Instance.GetInstance(ChunkPrefab).GetComponent<Chunk>();
|
|
c.UpdatePosition(Vector3.Scale(Vector3.one * Chunk.CHUNK_SIZE, new Vector3(pos.x, 0.0f, pos.y)));
|
|
chunks[pos] = c;
|
|
}
|
|
}
|
|
|
|
public const float noise_seed = 10000.0f;
|
|
|
|
public float GetPathCenter(float y)
|
|
{
|
|
float pathwayNoiseScale = 0.025f;
|
|
float pathwayBlockingNoiseLayer = (Mathf.PerlinNoise(0.5f, noise_seed + y * pathwayNoiseScale) * 2.0f) - 1.0f;
|
|
|
|
return pathwayBlockingNoiseLayer;
|
|
}
|
|
|
|
public float GetDistanceFromPath(float x, float y)
|
|
{
|
|
|
|
float distance = ((x/15.0f) - GetPathCenter(y));
|
|
|
|
return distance;
|
|
}
|
|
|
|
public float GetHeight(float x, float y)
|
|
{
|
|
float x_pow_2 = x * x;
|
|
float x_pow_3 = x * x * x;
|
|
float x_pow_4 = x * x * x * x;
|
|
|
|
float baseHeight = 0.000001f * x_pow_4;
|
|
|
|
float noise_scale_0 = 0.05f;
|
|
float noise_0 = Mathf.PerlinNoise(noise_seed + x * noise_scale_0, noise_seed + y * noise_scale_0) * 2.0f - 1.0f;
|
|
|
|
float noise_scale_1 = 0.001f;
|
|
float noise_1 = Mathf.PerlinNoise(noise_seed + x * noise_scale_1, noise_seed + y * noise_scale_1) * 2.0f - 1.0f;
|
|
|
|
float noise_scale_2 = 0.001f;
|
|
float noise_2 = Mathf.PerlinNoise(noise_seed + x * noise_scale_2, noise_seed + y * noise_scale_2) * 2.0f - 1.0f;
|
|
|
|
float distance = GetDistanceFromPath(x, y);
|
|
|
|
float height = baseHeight + (noise_0 * 5.0f) * TrenchProfile.Evaluate(distance) + noise_1 * 5.0f + noise_2 * 10.0f;
|
|
|
|
return height + ((TrenchProfile.Evaluate(distance)-1.0f)*3.0f);
|
|
}
|
|
}
|