From 1ad7266ade6e7db1976436d4cd322dc72c20d4bb Mon Sep 17 00:00:00 2001 From: miepzerino <o.skotnik@gmail.com> Date: Sun, 06 Apr 2025 16:48:56 +0000 Subject: [PATCH] #48 added chunk cache clear --- Assets/Scripts/GenerateTileMap.cs | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 99 insertions(+), 1 deletions(-) diff --git a/Assets/Scripts/GenerateTileMap.cs b/Assets/Scripts/GenerateTileMap.cs index 1d14849..4bf8585 100644 --- a/Assets/Scripts/GenerateTileMap.cs +++ b/Assets/Scripts/GenerateTileMap.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Unity.Collections; using Unity.Jobs; +using Unity.VisualScripting; using UnityEngine; using UnityEngine.Tilemaps; @@ -23,8 +24,11 @@ public const int CHUNK_SIZE = 16; // Size of each chunk public int LOAD_DISTANCE = 2; // Number of chunks to load around player + private const int CACHE_CLEAR_DISTANCE = 8; // Distance in chunks before clearing cache (should be > LOAD_DISTANCE) + private Vector2Int lastCacheClearPosition; // Track position where cache was last cleared private Dictionary<Vector2Int, bool> loadedChunks = new Dictionary<Vector2Int, bool>(); + private Dictionary<Vector2Int, TileBase[]> chunkCache = new Dictionary<Vector2Int, TileBase[]>(); private Transform playerTransform; // Reference to player/camera private Vector2Int lastLoadedChunk; private GameManager gameManager; @@ -59,6 +63,8 @@ { StartCoroutine(UpdateLoadedChunks(currentChunk)); lastLoadedChunk = currentChunk; + // Check if we need to clear the cache + ClearDistantChunks(currentChunk); } } @@ -206,16 +212,93 @@ Vector2Int chunkPos = new Vector2Int(centerChunk.x + x, centerChunk.y + y); if (!loadedChunks.ContainsKey(chunkPos)) { - yield return GenerateChunk(chunkPos, destroyedTiles); + if (chunkCache.ContainsKey(chunkPos)) + { + // Load the chunk from the cache + yield return LoadChunkFromCache(chunkPos); + } + else + { + // Generate the chunk + yield return GenerateChunk(chunkPos, destroyedTiles); + } loadedChunks[chunkPos] = true; } } + } + } + + private IEnumerator LoadChunkFromCache(Vector2Int chunk) + { + int startX = chunk.x * CHUNK_SIZE; + int startY = (chunk.y * CHUNK_SIZE) - 1; + + if (chunkCache.TryGetValue(chunk, out TileBase[] cachedTiles)) + { + for (int i = 0; i < cachedTiles.Length; i++) + { + int x = startX + (i % CHUNK_SIZE); + int y = startY - (i / CHUNK_SIZE); + Vector3Int tilePos = new Vector3Int(x, y); + + if (!IsTileDestroyed(tilePos)) + { + tilemap.SetTile(tilePos, cachedTiles[i]); + } + } + } + yield return null; + } + private void ClearDistantChunks(Vector2Int currentChunk) + { + // If this is the first time, initialize the last clear position + if (lastCacheClearPosition == default) + { + lastCacheClearPosition = currentChunk; + return; + } + + // Calculate distance moved since last cache clear + int distanceMoved = Mathf.Max( + Mathf.Abs(currentChunk.x - lastCacheClearPosition.x), + Mathf.Abs(currentChunk.y - lastCacheClearPosition.y) + ); + + // If we've moved far enough, clear distant chunks from cache + if (distanceMoved >= CACHE_CLEAR_DISTANCE) + { + List<Vector2Int> chunksToRemove = new List<Vector2Int>(); + + foreach (var chunk in chunkCache.Keys) + { + int distanceToPlayer = Mathf.Max( + Mathf.Abs(chunk.x - currentChunk.x), + Mathf.Abs(chunk.y - currentChunk.y) + ); + + // Remove chunks that are far from current position + if (distanceToPlayer > LOAD_DISTANCE * 2) + { + chunksToRemove.Add(chunk); + } + } + + // Remove the distant chunks from cache + foreach (var chunk in chunksToRemove) + { + chunkCache.Remove(chunk); + } + + lastCacheClearPosition = currentChunk; + Debug.Log($"Cleared {chunksToRemove.Count} chunks from cache. Current cache size: {chunkCache.Count}"); } } private IEnumerator GenerateChunk(Vector2Int chunk, List<Vector3Int> destroyedTiles) { int startX = chunk.x * CHUNK_SIZE; int startY = (chunk.y * CHUNK_SIZE) - 1; + // Check if the chunk is already in the cache + LoadChunkFromCache(chunk); // Create job data var groundJob = new GenerateGroundJob @@ -240,6 +323,7 @@ // Apply the results groundJobHandle.Complete(); + TileBase[] newChunkTiles = new TileBase[CHUNK_SIZE * CHUNK_SIZE]; for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE; i++) { if (groundJob.groundTiles[i]) @@ -251,9 +335,21 @@ if (!IsTileDestroyed(tilePos)) { tilemap.SetTile(tilePos, forestRuleTile); + newChunkTiles[i] = forestRuleTile; + } + else + { + newChunkTiles[i] = null; } } + else + { + newChunkTiles[i] = null; + } } + + // Save the generated chunk to the cache + chunkCache[chunk] = newChunkTiles; // Clean up native array groundJob.groundTiles.Dispose(); @@ -301,6 +397,7 @@ { float xPerlin = ((float)x / maxWidth) * (float)generateable.clusterWeight + offsetX; float yPerlin = ((float)Mathf.Abs(y) / maxDepth) * (float)generateable.clusterWeight + offsetY; + float perlinNoise = Mathf.PerlinNoise(xPerlin, yPerlin); if (perlinNoise <= (1f / (float)generateable.weight)) @@ -394,6 +491,7 @@ { perlinNoiseCache.Dispose(); } + chunkCache.Clear(); } #if UNITY_EDITOR private void OnDrawGizmos() -- Gitblit v1.9.3