using System.Linq; using System.Collections; using System.Collections.Generic; using UnityEngine; public class TerrainGenerator : Manager { 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 chunks = new Dictionary(); private const int LOAD_PER_UPDATE = 1; public void FixedUpdate() { HashSet loadedPositions = new HashSet(); 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> unload = chunks.Where(x => !loadedPositions.Contains(x.Key)).ToList(); foreach(KeyValuePair instance in unload) { PoolManager.Instance.ReturnInstance(instance.Value.gameObject); chunks.Remove(instance.Key); } List 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(); 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); } }