diff --git a/Assets/Scripts/Infrastructure/Unity/GameBootstrap.cs b/Assets/Scripts/Infrastructure/Unity/GameBootstrap.cs index 4b43341..0d27a03 100644 --- a/Assets/Scripts/Infrastructure/Unity/GameBootstrap.cs +++ b/Assets/Scripts/Infrastructure/Unity/GameBootstrap.cs @@ -70,7 +70,7 @@ namespace Infrastructure.Unity // Set Theme based on High Score ThemeManager.CurrentTheme = ThemeManager.GetTheme(_gameSession.HighScore); - var floorsCount = levelGenerator ? levelGenerator.FloorsCount : 1; + var floorsCount = levelGenerator ? levelGenerator.Definition.FloorCount : 1; if (levelGenerator) { @@ -133,8 +133,8 @@ namespace Infrastructure.Unity // Note: Generator uses negative offsets: 0, -15, -30. // So Floor 0 is at Y=0. Floor 1 is at Y=-15. - var heightDist = levelGenerator.FloorHeightDistance; - var maxFloors = levelGenerator.FloorsCount; + var heightDist = levelGenerator.Definition.FloorHeightDistance; + var maxFloors = levelGenerator.Definition.FloorCount; var rawFloor = Mathf.RoundToInt(-playerY / heightDist); _currentPlayerFloorIndex = Mathf.Clamp(rawFloor, 0, maxFloors - 1); @@ -250,10 +250,11 @@ namespace Infrastructure.Unity { if (!levelGenerator) return; - var lowestY = -(levelGenerator.FloorsCount * levelGenerator.FloorHeightDistance) - 5f; - var pos = new Vector3(levelGenerator.GridSizeX / 2f, lowestY, levelGenerator.GridSizeY / 2f); + var def = levelGenerator.Definition; + var lowestY = -(def.FloorCount * def.FloorHeightDistance) - 5f; + var pos = new Vector3(def.GridSizeX / 2f, lowestY, def.GridSizeY / 2f); var plane = Instantiate(deathPlanePrefab, pos, Quaternion.identity); - plane.transform.localScale = new Vector3(levelGenerator.GridSizeX * 200f, 1f, levelGenerator.GridSizeY * 200f); + plane.transform.localScale = new Vector3(def.GridSizeX * 200f, 1f, def.GridSizeY * 200f); plane.OnPlayerFell += () => _gameSession.EndGame(); } diff --git a/Assets/Scripts/Infrastructure/Unity/LevelDefinition.cs b/Assets/Scripts/Infrastructure/Unity/LevelDefinition.cs new file mode 100644 index 0000000..45237e2 --- /dev/null +++ b/Assets/Scripts/Infrastructure/Unity/LevelDefinition.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Infrastructure.Unity +{ + [CreateAssetMenu(fileName = "LevelDefinition", menuName = "Decay Grid/Level Definition")] + public class LevelDefinition : ScriptableObject + { + [SerializeField] private int gridSizeX = 10; + [SerializeField] private int gridSizeY = 10; + [SerializeField] private float floorHeightDistance = 15f; + [SerializeField] private FloorConfig[] floors = + { + new() { pattern = FloorPatternType.Square }, + new() { pattern = FloorPatternType.Donut }, + new() { pattern = FloorPatternType.Circle } + }; + + public int GridSizeX => gridSizeX; + public int GridSizeY => gridSizeY; + public float FloorHeightDistance => floorHeightDistance; + public int FloorCount => floors.Length; + public IReadOnlyList Floors => floors; + } + + [Serializable] + public class FloorConfig + { + public FloorPatternType pattern; + } + + public enum FloorPatternType + { + Square, + Donut, + Circle + } +} diff --git a/Assets/Scripts/Infrastructure/Unity/LevelGenerator.cs b/Assets/Scripts/Infrastructure/Unity/LevelGenerator.cs index 6c2ebcc..bfacd16 100644 --- a/Assets/Scripts/Infrastructure/Unity/LevelGenerator.cs +++ b/Assets/Scripts/Infrastructure/Unity/LevelGenerator.cs @@ -16,19 +16,15 @@ namespace Infrastructure.Unity [SerializeField] private JumpPadAdapter jumpPadPrefab; [SerializeField] private TeleporterAdapter teleporterPrefab; + [Header("Level")] + [SerializeField] private LevelDefinition levelDefinition; + [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; [SerializeField] private float minimumDistanceBetweenTeleporters = 3f; - public float FloorHeightDistance => floorHeightDistance; - public int FloorsCount => floorsCount; - public int GridSizeX => gridSizeX; - public int GridSizeY => gridSizeY; + public LevelDefinition Definition => levelDefinition; private TilePool _tilePool; @@ -39,20 +35,35 @@ namespace Infrastructure.Unity var stopwatch = new Stopwatch(); stopwatch.Start(); - yield return GenerateFloorAsync(0, MapPatterns.GenerateSquare(gridSizeX, gridSizeY), soundManager, registry, camera, rumble, stopwatch); - yield return GenerateFloorAsync(1, MapPatterns.GenerateDonut(gridSizeX, Mathf.FloorToInt(gridSizeX / 3f)), soundManager, registry, camera, rumble, stopwatch); - yield return GenerateFloorAsync(2, MapPatterns.GenerateCircle(gridSizeX), soundManager, registry, camera, rumble, stopwatch); + for (var i = 0; i < levelDefinition.FloorCount; i++) + { + var coords = GetCoordsForFloor(levelDefinition.Floors[i].pattern); + yield return GenerateFloorAsync(i, coords, soundManager, registry, camera, rumble, stopwatch); + } stopwatch.Stop(); onComplete?.Invoke(); } + private List GetCoordsForFloor(FloorPatternType pattern) + { + var sizeX = levelDefinition.GridSizeX; + var sizeY = levelDefinition.GridSizeY; + return pattern switch + { + FloorPatternType.Square => MapPatterns.GenerateSquare(sizeX, sizeY), + FloorPatternType.Donut => MapPatterns.GenerateDonut(sizeX, Mathf.FloorToInt(sizeX / 3f)), + FloorPatternType.Circle => MapPatterns.GenerateCircle(sizeX), + _ => MapPatterns.GenerateSquare(sizeX, sizeY) + }; + } + private IEnumerator GenerateFloorAsync(int floorIndex, List coordinates, SoundManager soundManager, TileRegistry registry, CameraController camera, RumbleManager rumble, Stopwatch stopwatch) { - var yOffset = -(floorIndex * floorHeightDistance); - var xOffset = gridSizeX / 2f; - var zOffset = gridSizeY / 2f; + var yOffset = -(floorIndex * levelDefinition.FloorHeightDistance); + var xOffset = levelDefinition.GridSizeX / 2f; + var zOffset = levelDefinition.GridSizeY / 2f; const long frameBudgetMs = 5;