|  |  |  | 
|---|
|  |  |  | private GameManager gameManager; | 
|---|
|  |  |  | private Dictionary<Vector2Int, HashSet<Vector3Int>> activeChunkTiles = new Dictionary<Vector2Int, HashSet<Vector3Int>>(); | 
|---|
|  |  |  | public TilePool tilePool; // Reference to the TilePool script | 
|---|
|  |  |  | private bool isGenerating = false; | 
|---|
|  |  |  | private bool isGenerating = false; | 
|---|
|  |  |  | private Dictionary<Vector2Int, List<(Vector3Int position, CustomRuleTile tile)>> chunkTileData = new Dictionary<Vector2Int, List<(Vector3Int position, CustomRuleTile tile)>>(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private void Awake() | 
|---|
|  |  |  | 
|---|
|  |  |  | Vector2Int currentChunk = GetChunkPosition(playerTransform.position); | 
|---|
|  |  |  | if (currentChunk != lastLoadedChunk) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | Debug.Log($"Player moved to new chunk: {currentChunk}"); | 
|---|
|  |  |  | isGenerating = true; | 
|---|
|  |  |  | StopAllCoroutines(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | foreach (var chunk in chunksToUnload) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | Debug.Log($"Unloading chunk: {chunk}"); | 
|---|
|  |  |  | UnloadChunk(chunk); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | Mathf.Abs(chunk.y - currentChunk.y) > LOAD_DISTANCE) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | chunksToUnload.Add(chunk); | 
|---|
|  |  |  | UnloadChunk(chunk); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | foreach (var chunk in chunksToUnload) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | UnloadChunk(chunk); | 
|---|
|  |  |  | loadedChunks.Remove(chunk); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | float adjustedX = worldPosition.x - transform.position.x; | 
|---|
|  |  |  | float adjustedY = worldPosition.y - transform.position.y; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return new Vector2Int( | 
|---|
|  |  |  | // Calculate chunk position based on chunk boundaries | 
|---|
|  |  |  | // We don't add the CHUNK_SIZE/2 offset here anymore since we want to detect based on boundaries | 
|---|
|  |  |  | Vector2Int chunkPosition = new Vector2Int( | 
|---|
|  |  |  | Mathf.FloorToInt(adjustedX / CHUNK_SIZE), | 
|---|
|  |  |  | Mathf.FloorToInt(adjustedY / CHUNK_SIZE) | 
|---|
|  |  |  | ); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return chunkPosition; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | private IEnumerator LoadChunksAroundPosition(Vector2Int centerChunk, List<Vector3Int> destroyedTiles) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | 
|---|
|  |  |  | Vector2Int chunkPos = new Vector2Int(centerChunk.x + x, centerChunk.y + y); | 
|---|
|  |  |  | if (!loadedChunks.ContainsKey(chunkPos)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | yield return GenerateChunk(chunkPos, destroyedTiles); | 
|---|
|  |  |  | if (chunkTileData.ContainsKey(chunkPos)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | Debug.Log($"Reloading chunk from saved data: {chunkPos}"); | 
|---|
|  |  |  | // Reload chunk from saved data | 
|---|
|  |  |  | var tilesToUpdate = chunkTileData[chunkPos]; | 
|---|
|  |  |  | const int BATCH_SIZE = 32; | 
|---|
|  |  |  | for (int i = 0; i < tilesToUpdate.Count; i += BATCH_SIZE) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | int batchCount = Math.Min(BATCH_SIZE, tilesToUpdate.Count - i); | 
|---|
|  |  |  | for (int j = 0; j < batchCount; j++) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | var (pos, tile) = tilesToUpdate[i + j]; | 
|---|
|  |  |  | SetTileWithPool(pos, tile); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | yield return null; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else | 
|---|
|  |  |  | { | 
|---|
|  |  |  | Debug.Log($"Generating new chunk: {chunkPos}"); | 
|---|
|  |  |  | // Generate new chunk | 
|---|
|  |  |  | yield return GenerateChunk(chunkPos, destroyedTiles); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | loadedChunks[chunkPos] = true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | if (terrainMap[i]) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | int x = startX + (i % CHUNK_SIZE); | 
|---|
|  |  |  | int y = startY - (i / CHUNK_SIZE); | 
|---|
|  |  |  | int y = startY + (i / CHUNK_SIZE); | 
|---|
|  |  |  | Vector3Int tilePos = new Vector3Int(x, y); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!IsTileDestroyed(tilePos)) | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // Save tile data to dictionary | 
|---|
|  |  |  | chunkTileData[chunk] = tilesToUpdate; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // Dispose native arrays before yielding | 
|---|
|  |  |  | terrainMap.Dispose(); | 
|---|
|  |  |  | noiseMap.Dispose(); | 
|---|
|  |  |  | 
|---|
|  |  |  | Vector2Int currentChunk = GetChunkPosition(playerTransform.position); | 
|---|
|  |  |  | Gizmos.color = Color.yellow; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // Draw player position for debugging | 
|---|
|  |  |  | Gizmos.color = Color.red; | 
|---|
|  |  |  | Gizmos.DrawSphere(playerTransform.position, 0.5f); | 
|---|
|  |  |  | Gizmos.color = Color.yellow; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | for (int x = -LOAD_DISTANCE; x <= LOAD_DISTANCE; x++) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | for (int y = -LOAD_DISTANCE; y <= LOAD_DISTANCE; y++) | 
|---|
|  |  |  | 
|---|
|  |  |  | new Vector3(CHUNK_SIZE, CHUNK_SIZE, 0) | 
|---|
|  |  |  | ); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // Draw chunk coordinates | 
|---|
|  |  |  | // Draw chunk coordinates and boundaries | 
|---|
|  |  |  | UnityEditor.Handles.Label( | 
|---|
|  |  |  | worldPos + new Vector3(CHUNK_SIZE / 2f, -CHUNK_SIZE / 2f, 0), | 
|---|
|  |  |  | $"({chunk.x}, {chunk.y})" | 
|---|
|  |  |  | $"({chunk.x}, {chunk.y})\n" + | 
|---|
|  |  |  | $"X: {worldPos.x} to {worldPos.x + CHUNK_SIZE}\n" + | 
|---|
|  |  |  | $"Y: {worldPos.y} to {worldPos.y - CHUNK_SIZE}" | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|