refactor: LevelDefinition ScriptableObject drives floor count and geometry
This commit is contained in:
@@ -70,7 +70,7 @@ namespace Infrastructure.Unity
|
|||||||
// Set Theme based on High Score
|
// Set Theme based on High Score
|
||||||
ThemeManager.CurrentTheme = ThemeManager.GetTheme(_gameSession.HighScore);
|
ThemeManager.CurrentTheme = ThemeManager.GetTheme(_gameSession.HighScore);
|
||||||
|
|
||||||
var floorsCount = levelGenerator ? levelGenerator.FloorsCount : 1;
|
var floorsCount = levelGenerator ? levelGenerator.Definition.FloorCount : 1;
|
||||||
|
|
||||||
if (levelGenerator)
|
if (levelGenerator)
|
||||||
{
|
{
|
||||||
@@ -133,8 +133,8 @@ namespace Infrastructure.Unity
|
|||||||
// Note: Generator uses negative offsets: 0, -15, -30.
|
// Note: Generator uses negative offsets: 0, -15, -30.
|
||||||
// So Floor 0 is at Y=0. Floor 1 is at Y=-15.
|
// So Floor 0 is at Y=0. Floor 1 is at Y=-15.
|
||||||
|
|
||||||
var heightDist = levelGenerator.FloorHeightDistance;
|
var heightDist = levelGenerator.Definition.FloorHeightDistance;
|
||||||
var maxFloors = levelGenerator.FloorsCount;
|
var maxFloors = levelGenerator.Definition.FloorCount;
|
||||||
|
|
||||||
var rawFloor = Mathf.RoundToInt(-playerY / heightDist);
|
var rawFloor = Mathf.RoundToInt(-playerY / heightDist);
|
||||||
_currentPlayerFloorIndex = Mathf.Clamp(rawFloor, 0, maxFloors - 1);
|
_currentPlayerFloorIndex = Mathf.Clamp(rawFloor, 0, maxFloors - 1);
|
||||||
@@ -250,10 +250,11 @@ namespace Infrastructure.Unity
|
|||||||
{
|
{
|
||||||
if (!levelGenerator) return;
|
if (!levelGenerator) return;
|
||||||
|
|
||||||
var lowestY = -(levelGenerator.FloorsCount * levelGenerator.FloorHeightDistance) - 5f;
|
var def = levelGenerator.Definition;
|
||||||
var pos = new Vector3(levelGenerator.GridSizeX / 2f, lowestY, levelGenerator.GridSizeY / 2f);
|
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);
|
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();
|
plane.OnPlayerFell += () => _gameSession.EndGame();
|
||||||
}
|
}
|
||||||
|
|||||||
39
Assets/Scripts/Infrastructure/Unity/LevelDefinition.cs
Normal file
39
Assets/Scripts/Infrastructure/Unity/LevelDefinition.cs
Normal file
@@ -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<FloorConfig> Floors => floors;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class FloorConfig
|
||||||
|
{
|
||||||
|
public FloorPatternType pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum FloorPatternType
|
||||||
|
{
|
||||||
|
Square,
|
||||||
|
Donut,
|
||||||
|
Circle
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,19 +16,15 @@ namespace Infrastructure.Unity
|
|||||||
[SerializeField] private JumpPadAdapter jumpPadPrefab;
|
[SerializeField] private JumpPadAdapter jumpPadPrefab;
|
||||||
[SerializeField] private TeleporterAdapter teleporterPrefab;
|
[SerializeField] private TeleporterAdapter teleporterPrefab;
|
||||||
|
|
||||||
|
[Header("Level")]
|
||||||
|
[SerializeField] private LevelDefinition levelDefinition;
|
||||||
|
|
||||||
[Header("Settings")]
|
[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 decayTime = 0.5f;
|
||||||
[SerializeField] private float fallingTime = 2.0f;
|
[SerializeField] private float fallingTime = 2.0f;
|
||||||
[SerializeField] private float minimumDistanceBetweenTeleporters = 3f;
|
[SerializeField] private float minimumDistanceBetweenTeleporters = 3f;
|
||||||
|
|
||||||
public float FloorHeightDistance => floorHeightDistance;
|
public LevelDefinition Definition => levelDefinition;
|
||||||
public int FloorsCount => floorsCount;
|
|
||||||
public int GridSizeX => gridSizeX;
|
|
||||||
public int GridSizeY => gridSizeY;
|
|
||||||
|
|
||||||
private TilePool _tilePool;
|
private TilePool _tilePool;
|
||||||
|
|
||||||
@@ -39,20 +35,35 @@ namespace Infrastructure.Unity
|
|||||||
var stopwatch = new Stopwatch();
|
var stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
|
|
||||||
yield return GenerateFloorAsync(0, MapPatterns.GenerateSquare(gridSizeX, gridSizeY), soundManager, registry, camera, rumble, stopwatch);
|
for (var i = 0; i < levelDefinition.FloorCount; i++)
|
||||||
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);
|
var coords = GetCoordsForFloor(levelDefinition.Floors[i].pattern);
|
||||||
|
yield return GenerateFloorAsync(i, coords, soundManager, registry, camera, rumble, stopwatch);
|
||||||
|
}
|
||||||
|
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
onComplete?.Invoke();
|
onComplete?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Vector2Int> 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<Vector2Int> coordinates, SoundManager soundManager,
|
private IEnumerator GenerateFloorAsync(int floorIndex, List<Vector2Int> coordinates, SoundManager soundManager,
|
||||||
TileRegistry registry, CameraController camera, RumbleManager rumble, Stopwatch stopwatch)
|
TileRegistry registry, CameraController camera, RumbleManager rumble, Stopwatch stopwatch)
|
||||||
{
|
{
|
||||||
var yOffset = -(floorIndex * floorHeightDistance);
|
var yOffset = -(floorIndex * levelDefinition.FloorHeightDistance);
|
||||||
var xOffset = gridSizeX / 2f;
|
var xOffset = levelDefinition.GridSizeX / 2f;
|
||||||
var zOffset = gridSizeY / 2f;
|
var zOffset = levelDefinition.GridSizeY / 2f;
|
||||||
|
|
||||||
const long frameBudgetMs = 5;
|
const long frameBudgetMs = 5;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user