1
0

EndlessTerrain.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using Unity.VisualScripting;
  4. public class EndlessTerrain : MonoBehaviour
  5. {
  6. public const float maxViewDst = 450f;
  7. public Transform viewer;
  8. public static Vector2 viewerPosition;
  9. int chunkSize;
  10. int chunksVisibleInViewDst;
  11. Dictionary<Vector2, TerrainChunk> terrainChunkDictionnary = new Dictionary<Vector2, TerrainChunk>();
  12. List<TerrainChunk> terrainChunksVisibleLastUpdate = new List<TerrainChunk>();
  13. private void Start()
  14. {
  15. chunkSize = MapGenerator.mapChunkSize - 1;
  16. chunksVisibleInViewDst = Mathf.RoundToInt(maxViewDst / chunkSize);
  17. }
  18. private void Update()
  19. {
  20. viewerPosition = new(viewer.position.x, viewer.position.z);
  21. UpdateVisibleChunks();
  22. }
  23. void UpdateVisibleChunks()
  24. {
  25. for (int i = 0; i < terrainChunksVisibleLastUpdate.Count; i++)
  26. {
  27. terrainChunksVisibleLastUpdate[i].SetVisible(false);
  28. }
  29. terrainChunksVisibleLastUpdate.Clear();
  30. int currentChunkCoordX = Mathf.RoundToInt(viewerPosition.x / chunkSize);
  31. int currentChunkCoordY = Mathf.RoundToInt(viewerPosition.y / chunkSize);
  32. for (int yOffset = -chunksVisibleInViewDst; yOffset <=chunksVisibleInViewDst; yOffset++)
  33. {
  34. for (int xOffset = -chunksVisibleInViewDst; xOffset <= chunksVisibleInViewDst; xOffset++)
  35. {
  36. Vector2 viewedChunkCoord = new(currentChunkCoordX + xOffset, currentChunkCoordY + yOffset);
  37. if (terrainChunkDictionnary.ContainsKey(viewedChunkCoord))
  38. {
  39. terrainChunkDictionnary[viewedChunkCoord].UpdateTerrainChunk();
  40. if (terrainChunkDictionnary[viewedChunkCoord].IsVisible())
  41. {
  42. terrainChunksVisibleLastUpdate.Add(terrainChunkDictionnary[viewedChunkCoord]);
  43. }
  44. }
  45. else
  46. {
  47. terrainChunkDictionnary.Add(viewedChunkCoord, new TerrainChunk(viewedChunkCoord, chunkSize, transform));
  48. }
  49. }
  50. }
  51. }
  52. public class TerrainChunk
  53. {
  54. GameObject meshObject;
  55. Vector2 position;
  56. Bounds bounds;
  57. public TerrainChunk(Vector2 coord, int size, Transform parent)
  58. {
  59. position = coord * size;
  60. bounds = new Bounds(position, Vector2.one * size);
  61. Vector3 positionV3 = new(position.x, 0, position.y);
  62. meshObject = GameObject.CreatePrimitive(PrimitiveType.Plane);
  63. meshObject.transform.position = positionV3;
  64. meshObject.transform.localScale = Vector3.one * size / 10f;
  65. meshObject.transform.parent = parent;
  66. SetVisible(false);
  67. }
  68. public void UpdateTerrainChunk()
  69. {
  70. float viewDstFromNearestEdge = Mathf.Sqrt(bounds.SqrDistance(viewerPosition));
  71. bool visible = viewDstFromNearestEdge <= maxViewDst;
  72. SetVisible(visible);
  73. }
  74. public void SetVisible(bool visible)
  75. {
  76. meshObject.SetActive(visible);
  77. }
  78. public bool IsVisible()
  79. {
  80. return meshObject.activeSelf;
  81. }
  82. }
  83. }