using System.Collections.Generic; using Core.Domain; using UnityEngine; namespace Infrastructure.Unity { public class LevelGenerator : MonoBehaviour { [Header("Prefabs")] [SerializeField] private TileViewAdapter tilePrefab; [SerializeField] private ParticleSystem tileBreakVfxPrefab; [SerializeField] private JumpPadAdapter jumpPadPrefab; [Header("Settings")] [SerializeField] private int gridSizeX = 10; [SerializeField] private int gridSizeY = 10; [SerializeField] private int floorsCount = 3; [SerializeField] private float floorHeightDistance = 15f; [SerializeField] private float decayTime = 0.5f; [SerializeField] private float fallingTime = 2.0f; public float FloorHeightDistance => floorHeightDistance; public int FloorsCount => floorsCount; public int GridSizeX => gridSizeX; public int GridSizeY => gridSizeY; public void Generate(SoundManager soundManager, List allTiles, Dictionary tileViews) { GenerateFloor(0, MapPatterns.GenerateSquare(gridSizeX, gridSizeY), soundManager, allTiles, tileViews); GenerateFloor(1, MapPatterns.GenerateDonut(gridSizeX, Mathf.FloorToInt(gridSizeX / 3f)), soundManager, allTiles, tileViews); GenerateFloor(2, MapPatterns.GenerateCircle(gridSizeX), soundManager, allTiles, tileViews); } private void GenerateFloor(int floorIndex, List coordinates, SoundManager soundManager, List allTiles, Dictionary tileViews) { var yOffset = -(floorIndex * floorHeightDistance); var xOffset = gridSizeX / 2f; var zOffset = gridSizeY / 2f; foreach (var coord in coordinates) { var pos = new Vector3(coord.x - xOffset, yOffset, coord.y - zOffset); CreateTile(pos, $"{floorIndex}_{coord.x}_{coord.y}", floorIndex, soundManager, allTiles, tileViews); } if (floorIndex > 0 && jumpPadPrefab) { var validSpot = coordinates[Random.Range(0, coordinates.Count)]; var padPos = new Vector3(validSpot.x - xOffset, yOffset + 0.6f, validSpot.y - zOffset); Instantiate(jumpPadPrefab, padPos, Quaternion.identity, transform); } } private void CreateTile(Vector3 position, string id, int floorIndex, SoundManager soundManager, List allTiles, Dictionary tileViews) { var go = Instantiate(tilePrefab, position, Quaternion.identity, transform); go.transform.localScale = Vector3.one * 0.95f; var tileLogic = new Tile(id, floorIndex, decayTime, fallingTime); go.Initialize(tileLogic); if (soundManager) { tileLogic.OnStateChanged += (t) => { if (t.CurrentState == TileState.Warning) { soundManager.PlayTileWarning(position); } else if (t.CurrentState == TileState.Falling) { soundManager.PlayTileBreak(position); if (tileBreakVfxPrefab) { Instantiate(tileBreakVfxPrefab, position, Quaternion.identity); } } }; } allTiles.Add(tileLogic); tileViews.Add(id, go); } } }