From 2dfa4588b3b5bba2a84dab239d62b1c285478870 Mon Sep 17 00:00:00 2001 From: miepzerino <o.skotnik@gmail.com> Date: Wed, 02 Apr 2025 22:31:45 +0000 Subject: [PATCH] inventory scrollbar autohide --- Assets/Scripts/FogOfWar.cs | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 203 insertions(+), 0 deletions(-) diff --git a/Assets/Scripts/FogOfWar.cs b/Assets/Scripts/FogOfWar.cs new file mode 100644 index 0000000..251c3ce --- /dev/null +++ b/Assets/Scripts/FogOfWar.cs @@ -0,0 +1,203 @@ +using UnityEngine; +using UnityEngine.Tilemaps; + +public class FogOfWar : MonoBehaviour +{ + public Tilemap fogTilemap; + public TileBase fogTile; + public Transform player; + public int viewRadius = 5; + public Camera mainCamera; + + private Vector3Int lastPlayerCell; + private const float UpdateInterval = 0.1f; // Update every 100ms + private float updateTimer; + private TileBase[,] discoveredFog; // Store the lowest opacity fog level for each tile + + [System.Serializable] + public class FogLevel + { + public TileBase tile; + public float opacity; + } + public FogLevel[] fogLevels; + + private void Start() + { + if (mainCamera == null) + mainCamera = Camera.main; + // Initialize the discovered fog array + int fogDepth = GenerateTileMap.groundDepth - 1; // Subtract 2 to account for array starting at y=-3 + discoveredFog = new TileBase[GenerateTileMap.maxWidth + 1, fogDepth]; + // Initialize fog using GenerateTileMap bounds + for (int x = 0; x <= GenerateTileMap.maxWidth; x++) + { + // Clear surface tiles (0 to -1) + for (int y = 0; y >= -1; y--) + { + Vector3Int tilePosition = new Vector3Int(x, y, 0); + fogTilemap.SetTile(tilePosition, null); + } + + // Set fog for underground tiles (-2 and below) + for (int y = -2; y >= -GenerateTileMap.groundDepth; y--) + { + Vector3Int tilePosition = new Vector3Int(x, y, 0); + fogTilemap.SetTile(tilePosition, fogTile); + + // Convert to array index (y=-2 maps to array index 0) + int arrayY = Mathf.Abs(y + 2); + discoveredFog[x, arrayY] = fogTile; + } + } + + // Position the fog tilemap at the same position as the main tilemap + fogTilemap.transform.position = new Vector3( + (GenerateTileMap.maxWidth / 2) * -1, + -1, + transform.position.z + ); + lastPlayerCell = fogTilemap.WorldToCell(player.position); + + if (SaveSystem.isGameLoaded) + { + SaveDataMap mapState = SaveSystem.LoadMapState(); + if (mapState != null && mapState.fogOfWarData != null) + { + GetComponent<FogOfWar>().LoadFromSaveData(mapState.fogOfWarData); + } + } + } + + private void Update() + { + updateTimer += Time.deltaTime; + if (updateTimer < UpdateInterval) + return; + updateTimer = 0; + Vector3Int playerCell = fogTilemap.WorldToCell(player.position); + + // Only update if player moved to a new cell + if (playerCell == lastPlayerCell) + return; + + lastPlayerCell = playerCell; + + // Get camera bounds in world space + Vector2 cameraMin = mainCamera.ViewportToWorldPoint(new Vector3(0, 0)); + Vector2 cameraMax = mainCamera.ViewportToWorldPoint(new Vector3(1, 1)); + // Convert to tile coordinates + Vector3Int tileMin = fogTilemap.WorldToCell(cameraMin); + Vector3Int tileMax = fogTilemap.WorldToCell(cameraMax); + // Clamp to map bounds + tileMin.x = Mathf.Max(0, tileMin.x - viewRadius); + tileMin.y = Mathf.Max(-GenerateTileMap.groundDepth, tileMin.y - viewRadius); + tileMax.x = Mathf.Min(GenerateTileMap.maxWidth, tileMax.x + viewRadius); + tileMax.y = Mathf.Min(-2, tileMax.y + viewRadius); + + // Clear fog around player + // Only check tiles within camera view + for (int x = tileMin.x; x <= tileMax.x; x++) + { + for (int y = tileMin.y; y <= tileMax.y; y++) + { + Vector3Int tilePosition = new Vector3Int(x, y, 0); + float distance = Vector2.Distance(((Vector2Int)playerCell), (Vector2Int)tilePosition); + + if (distance <= viewRadius) + { + int fogIndex = Mathf.FloorToInt((distance / viewRadius) * (fogLevels.Length - 1)); + fogIndex = Mathf.Clamp(fogIndex, 0, fogLevels.Length - 1); + + TileBase newFogTile = distance <= 1 ? null : fogLevels[fogIndex].tile; + + // Update the discovered state with the lowest opacity (null or lower fog index) + int arrayY = Mathf.Abs(y + 2); // y=-2 maps to array index 0 + if (x >= 0 && x < discoveredFog.GetLength(0) && + arrayY >= 0 && arrayY < discoveredFog.GetLength(1)) + { + if (newFogTile == null) + { + discoveredFog[x, arrayY] = null; + } + else if (discoveredFog[x, arrayY] != null) + { + // Find the index of the current and new fog tiles + int currentIndex = System.Array.FindIndex(fogLevels, f => f.tile == discoveredFog[x, arrayY]); + int newIndex = System.Array.FindIndex(fogLevels, f => f.tile == newFogTile); + + // Keep the lower opacity version + if (newIndex < currentIndex) + { + discoveredFog[x, arrayY] = newFogTile; + } + } + + // Always use the discovered state + fogTilemap.SetTile(tilePosition, discoveredFog[x, arrayY]); + } + } + } + } + } + + public FogOfWarData GetSaveData() + { + FogOfWarData saveData = new FogOfWarData(); + + for (int x = 0; x < discoveredFog.GetLength(0); x++) + { + for (int y = 0; y < discoveredFog.GetLength(1); y++) + { + TileBase currentTile = discoveredFog[x, y]; + if (currentTile == null || currentTile != fogTile) // Only save revealed tiles + { + FogTileData tileData = new FogTileData + { + x = x, + y = y, + fogLevelIndex = currentTile == null ? -1 : System.Array.FindIndex(fogLevels, f => f.tile == currentTile) + }; + saveData.discoveredTiles.Add(tileData); + } + } + } + + return saveData; + } + + public void LoadFromSaveData(FogOfWarData saveData) + { + if (saveData == null || saveData.discoveredTiles == null) + return; + + // Reset fog to full opacity + for (int x = 0; x < discoveredFog.GetLength(0); x++) + { + // Reset underground tiles only (-2 and below) + for (int y = -2; y >= -GenerateTileMap.groundDepth; y--) + { + Vector3Int tilePosition = new Vector3Int(x, y, 0); + fogTilemap.SetTile(tilePosition, fogTile); + + int arrayY = Mathf.Abs(y + 2); + discoveredFog[x, arrayY] = fogTile; + } + } + + // Apply saved fog states + foreach (FogTileData tileData in saveData.discoveredTiles) + { + if (tileData.x >= 0 && tileData.x < discoveredFog.GetLength(0) && + tileData.y >= 0 && tileData.y < discoveredFog.GetLength(1)) + { + TileBase tileToUse = tileData.fogLevelIndex == -1 ? null : fogLevels[tileData.fogLevelIndex].tile; + discoveredFog[tileData.x, tileData.y] = tileToUse; + + // Convert array Y coordinate back to world Y coordinate + int worldY = -(tileData.y + 2); // Convert array index back to world coordinates + fogTilemap.SetTile(new Vector3Int(tileData.x, worldY, 0), tileToUse); + } + } + } +} -- Gitblit v1.9.3