瀏覽代碼

Procedural Generation 7/21

Nathan Gusatto 1 月之前
父節點
當前提交
69135b8221

文件差異過大導致無法顯示
+ 0 - 35
Assets/Scenes/SampleScene.unity


+ 97 - 0
Assets/Scripts/EndlessTerrain.cs

@@ -0,0 +1,97 @@
+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;
+        }
+    }
+}

+ 2 - 0
Assets/Scripts/EndlessTerrain.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 56b8a3326a5b55645b3103bc60875760

+ 1 - 1
Assets/Scripts/MapGenerator.cs

@@ -6,7 +6,7 @@ public class MapGenerator : MonoBehaviour
     public enum DrawMode { NoiseMap, ColourMap, Mesh};
     public DrawMode drawMode;
 
-    const int mapChunkSize = 241;
+    public const int mapChunkSize = 241;
 
     [Range(0,6)]
     public int levelOfDetail;

部分文件因文件數量過多而無法顯示