| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- using UnityEngine;
- using System.Collections.Generic;
- using Unity.VisualScripting;
- public class EndlessTerrain : MonoBehaviour
- {
- public const float maxViewDst = 450f;
- public Transform viewer;
- public static Vector2 viewerPosition;
- int chunkSize;
- int chunksVisibleInViewDst;
- Dictionary<Vector2, TerrainChunk> terrainChunkDictionnary = new Dictionary<Vector2, TerrainChunk>();
- List<TerrainChunk> terrainChunksVisibleLastUpdate = new List<TerrainChunk>();
- private void Start()
- {
- chunkSize = MapGenerator.mapChunkSize - 1;
- chunksVisibleInViewDst = Mathf.RoundToInt(maxViewDst / chunkSize);
- }
- private void Update()
- {
- viewerPosition = new(viewer.position.x, viewer.position.z);
- UpdateVisibleChunks();
- }
- void UpdateVisibleChunks()
- {
- for (int i = 0; i < terrainChunksVisibleLastUpdate.Count; i++)
- {
- terrainChunksVisibleLastUpdate[i].SetVisible(false);
- }
- terrainChunksVisibleLastUpdate.Clear();
- int currentChunkCoordX = Mathf.RoundToInt(viewerPosition.x / chunkSize);
- int currentChunkCoordY = Mathf.RoundToInt(viewerPosition.y / chunkSize);
- for (int yOffset = -chunksVisibleInViewDst; yOffset <=chunksVisibleInViewDst; yOffset++)
- {
- for (int xOffset = -chunksVisibleInViewDst; xOffset <= chunksVisibleInViewDst; xOffset++)
- {
- Vector2 viewedChunkCoord = new(currentChunkCoordX + xOffset, currentChunkCoordY + yOffset);
- if (terrainChunkDictionnary.ContainsKey(viewedChunkCoord))
- {
- terrainChunkDictionnary[viewedChunkCoord].UpdateTerrainChunk();
- if (terrainChunkDictionnary[viewedChunkCoord].IsVisible())
- {
- terrainChunksVisibleLastUpdate.Add(terrainChunkDictionnary[viewedChunkCoord]);
- }
- }
- else
- {
- terrainChunkDictionnary.Add(viewedChunkCoord, new TerrainChunk(viewedChunkCoord, chunkSize, transform));
- }
- }
- }
- }
- public class TerrainChunk
- {
- GameObject meshObject;
- Vector2 position;
- Bounds bounds;
- public TerrainChunk(Vector2 coord, int size, Transform parent)
- {
- position = coord * size;
- bounds = new Bounds(position, Vector2.one * size);
- Vector3 positionV3 = new(position.x, 0, position.y);
- meshObject = GameObject.CreatePrimitive(PrimitiveType.Plane);
- meshObject.transform.position = positionV3;
- meshObject.transform.localScale = Vector3.one * size / 10f;
- meshObject.transform.parent = parent;
- SetVisible(false);
- }
- public void UpdateTerrainChunk()
- {
- float viewDstFromNearestEdge = Mathf.Sqrt(bounds.SqrDistance(viewerPosition));
- bool visible = viewDstFromNearestEdge <= maxViewDst;
- SetVisible(visible);
- }
- public void SetVisible(bool visible)
- {
- meshObject.SetActive(visible);
- }
- public bool IsVisible()
- {
- return meshObject.activeSelf;
- }
- }
- }
|