From ad8af928065a506d0d28f98d51222d7afa1f47e2 Mon Sep 17 00:00:00 2001 From: miepzerino <o.skotnik@gmail.com> Date: Sat, 05 Apr 2025 14:55:22 +0000 Subject: [PATCH] #47 background rework (static with transitions) --- Assets/Scripts/GenerateTileMap.cs | 82 ++++++++++++++++++++++++++++------------- 1 files changed, 56 insertions(+), 26 deletions(-) diff --git a/Assets/Scripts/GenerateTileMap.cs b/Assets/Scripts/GenerateTileMap.cs index 168a4eb..1c01f5d 100644 --- a/Assets/Scripts/GenerateTileMap.cs +++ b/Assets/Scripts/GenerateTileMap.cs @@ -1,11 +1,10 @@ using System; using System.Collections; using System.Collections.Generic; -using Unity.VisualScripting; +using Unity.Collections; +using Unity.Jobs; using UnityEngine; using UnityEngine.Tilemaps; -using UnityEngine.UIElements; -using static UnityEditor.Progress; //[Serializable] //public class Ore @@ -46,7 +45,7 @@ //public List<TileBase> tiles; public const int CHUNK_SIZE = 16; // Size of each chunk - public const int LOAD_DISTANCE = 2; // Number of chunks to load around player + public int LOAD_DISTANCE = 2; // Number of chunks to load around player private Dictionary<Vector2Int, bool> loadedChunks = new Dictionary<Vector2Int, bool>(); private Transform playerTransform; // Reference to player/camera @@ -76,9 +75,9 @@ private void Update() { if (playerTransform == null) return; - Debug.Log($"Player Position: {playerTransform.position}"); + //Debug.Log($"Player Position: {playerTransform.position}"); Vector2Int currentChunk = GetChunkPosition(playerTransform.position); - Debug.Log($"Current Chunk: {currentChunk}"); + //Debug.Log($"Current Chunk: {currentChunk}"); if (currentChunk != lastLoadedChunk) { StartCoroutine(UpdateLoadedChunks(currentChunk)); @@ -207,7 +206,7 @@ { // Adjust for tilemap offset float adjustedX = worldPosition.x - transform.position.x; - float adjustedY = worldPosition.y - transform.position.y; + float adjustedY = (worldPosition.y - transform.position.y) + CHUNK_SIZE; return new Vector2Int( Mathf.FloorToInt(adjustedX / CHUNK_SIZE), @@ -232,38 +231,54 @@ private IEnumerator GenerateChunk(Vector2Int chunk, List<Vector3Int> destroyedTiles) { int startX = chunk.x * CHUNK_SIZE; - int startY = (chunk.y * CHUNK_SIZE)-1; + int startY = (chunk.y * CHUNK_SIZE) - 1; - // Generate ground in chunk - for (int x = startX; x < startX + CHUNK_SIZE; x++) + // Create job data + var groundJob = new GenerateGroundJob { - if (x < 1 || x >= maxWidth) continue; + chunkStartX = startX, + chunkStartY = startY, + chunkSize = CHUNK_SIZE, + maxWidth = maxWidth, + groundDepth = groundDepth, + scale = scale, + offsetX = offsetX, + offsetY = offsetY, + groundTiles = new NativeArray<bool>(CHUNK_SIZE * CHUNK_SIZE, Allocator.TempJob) + }; - for (int y = startY; y > startY - CHUNK_SIZE; y--) + // Schedule the job + JobHandle groundJobHandle = groundJob.Schedule(CHUNK_SIZE * CHUNK_SIZE, 64); + + // Wait for the job to complete + groundJobHandle.Complete(); + + // Apply the results + for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE; i++) + { + if (groundJob.groundTiles[i]) { - if (y < -groundDepth || y >= 0) continue; + int x = startX + (i % CHUNK_SIZE); + int y = startY - (i / CHUNK_SIZE); Vector3Int tilePos = new Vector3Int(x, y); - if (IsTileDestroyed(tilePos)) - continue; - float xPerlin = ((float)x / maxWidth) * scale + offsetX; - float yPerlin = ((float)Mathf.Abs(y) / maxDepth) * scale + offsetY; - float perlinNoise = Mathf.PerlinNoise(xPerlin, yPerlin); - - if (perlinNoise <= 0.7f) + if (!IsTileDestroyed(tilePos)) { tilemap.SetTile(tilePos, forestRuleTile); } } } - // Generate ores in chunk + // Clean up native array + groundJob.groundTiles.Dispose(); + + // Generate ores if (generateables != null) { yield return GenerateOresInChunk(chunk, destroyedTiles); } - // Don't generate borders for each chunk - // Only generate borders when at world edges + + // Generate borders when needed if (startX == 0 || startX + CHUNK_SIZE >= maxWidth || startY == 0 || startY - CHUNK_SIZE <= -groundDepth) { @@ -309,15 +324,22 @@ // Convert spawn heights to negative values if they aren't already int maxY = -Mathf.Abs(generateable.maxSpawnHeight); int minY = -Mathf.Abs(generateable.minSpawnHeight); + // Changed condition: Check if the chunk's Y range overlaps with ore spawn range + int chunkMaxY = startY; + int chunkMinY = startY - CHUNK_SIZE; // Only process this chunk if it's within the ore's spawn height range - if (startY < maxY && startY > minY) + if (chunkMinY <= maxY && chunkMaxY >= minY) { for (int x = startX; x < startX + CHUNK_SIZE; x++) { if (x >= maxWidth) continue; - for (int y = Mathf.Max(startY - CHUNK_SIZE, minY); y < Mathf.Min(startY, maxY); y++) + // Adjusted Y range calculation + int rangeStart = Mathf.Max(chunkMinY, minY); + int rangeEnd = Mathf.Min(chunkMaxY, maxY); + + for (int y = rangeStart; y <= rangeEnd; y++) { float xPerlin = ((float)x / maxWidth) * (float)generateable.clusterWeight + offsetX; float yPerlin = ((float)Mathf.Abs(y) / maxDepth) * (float)generateable.clusterWeight + offsetY; @@ -328,7 +350,6 @@ Vector3Int tileSpawnCoord = new Vector3Int(x, y); if (!destroyedTiles.Contains(tileSpawnCoord) && tilemap.HasTile(tileSpawnCoord)) { - // Check potential cluster size before placing int clusterSize = CountPotentialClusterSize(x, y, generateable.weight, generateable.clusterWeight); if (clusterSize >= generateable.minClusterSize) { @@ -452,6 +473,7 @@ return size; } +#if UNITY_EDITOR private void OnDrawGizmos() { if (!Application.isPlaying) return; @@ -473,12 +495,20 @@ 0 ); + // Draw chunk boundary Gizmos.DrawWireCube( worldPos + new Vector3(CHUNK_SIZE / 2f, -CHUNK_SIZE / 2f, 0), new Vector3(CHUNK_SIZE, CHUNK_SIZE, 0) + ); + + // Draw chunk coordinates + UnityEditor.Handles.Label( + worldPos + new Vector3(CHUNK_SIZE / 2f, -CHUNK_SIZE / 2f, 0), + $"({chunk.x}, {chunk.y})" ); } } } } +#endif } -- Gitblit v1.9.3