private void UpdateVisibleChunks()
        {
            HashSet <Vector2> alreadyUpdatedChunks = new HashSet <Vector2>();

            for (int i = visibleTerrainChunks.Count - 1; i >= 0; --i)
            {
                alreadyUpdatedChunks.Add(visibleTerrainChunks[i].coord);
                visibleTerrainChunks[i].UpdateTerrainChunk();
            }

            int currentChunkCoordX = Mathf.RoundToInt(viewerPosition.x / meshWorldSize);
            int currentChunkCoordY = Mathf.RoundToInt(viewerPosition.y / meshWorldSize);

            for (int yOffset = -chunksVisibleInViewDist; yOffset <= chunksVisibleInViewDist; ++yOffset)
            {
                for (int xOffset = -chunksVisibleInViewDist; xOffset <= chunksVisibleInViewDist; ++xOffset)
                {
                    Vector2 viewedChunkCoord = new Vector2(currentChunkCoordX + xOffset, currentChunkCoordY + yOffset);
                    if (!terrainChunks.TryGetValue(viewedChunkCoord, out TerrainChunk chunk))
                    {
                        TerrainChunk newChunk = new TerrainChunk(viewedChunkCoord, heightMapSettings, meshSettings,
                                                                 detailLevels, colliderLODIndex, transform, viewer, mapMaterial);
                        terrainChunks.Add(viewedChunkCoord,
                                          newChunk);
                        newChunk.OnVisibilityChanged += OnTerrainChunkVisibilityChanged;
                        newChunk.Load();
                    }
                    else if (!alreadyUpdatedChunks.Contains(viewedChunkCoord))
                    {
                        chunk.UpdateTerrainChunk();
                    }
                }
            }
        }
 void OnTerrainChunkVisibilityChanged(TerrainChunk chunk, bool isVisible)
 {
     if (isVisible)
     {
         visibleTerrainChunks.Add(chunk);
     }
     else
     {
         visibleTerrainChunks.Remove(chunk);
     }
 }