Refactor level generation to use asynchronous processing; improve performance with frame budget management

This commit is contained in:
2025-12-13 03:09:06 +01:00
parent 1ae7190fd3
commit e5388bc5e0
3 changed files with 44 additions and 20 deletions

View File

@@ -71,24 +71,29 @@ namespace Infrastructure.Unity
if (levelGenerator) if (levelGenerator)
{ {
levelGenerator.Generate(soundManager, _allTiles, _tileViews, cameraController, rumbleManager); StartCoroutine(levelGenerator.GenerateAsync(soundManager, _allTiles, _tileViews, cameraController,
rumbleManager,
() =>
{
if (!floorVisibilityManager)
{
floorVisibilityManager = gameObject.AddComponent<FloorVisibilityManager>();
}
floorVisibilityManager.Initialize(_gameSession, _allTiles, _tileViews, floorsCount);
if (!floorVisibilityManager) SpawnDeathPlane();
{ SpawnPlayer();
floorVisibilityManager = gameObject.AddComponent<FloorVisibilityManager>();
}
floorVisibilityManager.Initialize(_gameSession, _allTiles, _tileViews, floorsCount); if (gameOverUi) gameOverUi.SetActive(false);
if (startScreenUi) startScreenUi.SetActive(true); // Show start screen NOW
WireEvents();
UpdateScoreUi(_gameSession.Score);
}));
} }
SpawnDeathPlane();
SpawnPlayer();
if (gameOverUi) gameOverUi.SetActive(false); if (gameOverUi) gameOverUi.SetActive(false);
if (startScreenUi) startScreenUi.SetActive(true); if (startScreenUi) startScreenUi.SetActive(true);
WireEvents();
UpdateScoreUi(_gameSession.Score);
} }
private void Update() private void Update()

View File

@@ -1,6 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using Core.Domain; using Core.Domain;
using UnityEngine; using UnityEngine;
using Random = UnityEngine.Random;
namespace Infrastructure.Unity namespace Infrastructure.Unity
{ {
@@ -28,26 +32,41 @@ namespace Infrastructure.Unity
private TilePool _tilePool; private TilePool _tilePool;
public void Generate(SoundManager soundManager, List<Tile> allTiles, Dictionary<string, TileViewAdapter> tileViews, CameraController camera, RumbleManager rumble) public IEnumerator GenerateAsync(SoundManager soundManager, List<Tile> allTiles, Dictionary<string, TileViewAdapter> tileViews, CameraController camera, RumbleManager rumble, Action onComplete)
{ {
_tilePool = new TilePool(tilePrefab, transform); _tilePool = new TilePool(tilePrefab, transform);
GenerateFloor(0, MapPatterns.GenerateSquare(gridSizeX, gridSizeY), soundManager, allTiles, tileViews, camera, rumble); var stopwatch = new Stopwatch();
GenerateFloor(1, MapPatterns.GenerateDonut(gridSizeX, Mathf.FloorToInt(gridSizeX / 3f)), soundManager, allTiles, tileViews, camera, rumble); stopwatch.Start();
GenerateFloor(2, MapPatterns.GenerateCircle(gridSizeX), soundManager, allTiles, tileViews, camera, rumble);
yield return GenerateFloorAsync(0, MapPatterns.GenerateSquare(gridSizeX, gridSizeY), soundManager, allTiles, tileViews, camera, rumble, stopwatch);
yield return GenerateFloorAsync(1, MapPatterns.GenerateDonut(gridSizeX, Mathf.FloorToInt(gridSizeX / 3f)), soundManager, allTiles, tileViews, camera, rumble, stopwatch);
yield return GenerateFloorAsync(2, MapPatterns.GenerateCircle(gridSizeX), soundManager, allTiles, tileViews, camera, rumble, stopwatch);
stopwatch?.Stop();
onComplete?.Invoke();
} }
private void GenerateFloor(int floorIndex, List<Vector2Int> coordinates, SoundManager soundManager, private IEnumerator GenerateFloorAsync(int floorIndex, List<Vector2Int> coordinates, SoundManager soundManager,
List<Tile> allTiles, Dictionary<string, TileViewAdapter> tileViews, CameraController camera, RumbleManager rumble) List<Tile> allTiles, Dictionary<string, TileViewAdapter> tileViews, CameraController camera, RumbleManager rumble, Stopwatch stopwatch)
{ {
var yOffset = -(floorIndex * floorHeightDistance); var yOffset = -(floorIndex * floorHeightDistance);
var xOffset = gridSizeX / 2f; var xOffset = gridSizeX / 2f;
var zOffset = gridSizeY / 2f; var zOffset = gridSizeY / 2f;
const long frameBudgetMs = 5;
foreach (var coord in coordinates) foreach (var coord in coordinates)
{ {
var pos = new Vector3(coord.x - xOffset, yOffset, coord.y - zOffset); var pos = new Vector3(coord.x - xOffset, yOffset, coord.y - zOffset);
CreateTile(pos, $"{floorIndex}_{coord.x}_{coord.y}", floorIndex, soundManager, allTiles, tileViews, camera, rumble); CreateTile(pos, $"{floorIndex}_{coord.x}_{coord.y}", floorIndex, soundManager, allTiles, tileViews, camera, rumble);
if (stopwatch.ElapsedMilliseconds > frameBudgetMs)
{
stopwatch.Reset();
stopwatch.Start();
yield return null; // Wait for next frame
}
} }
if (floorIndex > 0 && jumpPadPrefab) if (floorIndex > 0 && jumpPadPrefab)

View File

@@ -17,7 +17,7 @@ PhysicsManager:
m_EnableAdaptiveForce: 0 m_EnableAdaptiveForce: 0
m_ClothInterCollisionDistance: 0.1 m_ClothInterCollisionDistance: 0.1
m_ClothInterCollisionStiffness: 0.2 m_ClothInterCollisionStiffness: 0.2
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff m_LayerCollisionMatrix: fffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_SimulationMode: 0 m_SimulationMode: 0
m_AutoSyncTransforms: 0 m_AutoSyncTransforms: 0
m_ReuseCollisionCallbacks: 1 m_ReuseCollisionCallbacks: 1