Before placing PLaceholders

This commit is contained in:
2025-12-14 20:55:37 +01:00
parent 8e1fa9fb97
commit 8259597442
15 changed files with 624 additions and 29 deletions

View File

@@ -31,9 +31,27 @@ namespace Minigames.BirdPooper
[Tooltip("Array of obstacle prefabs to spawn randomly")]
[SerializeField] private GameObject[] obstaclePrefabs;
[Header("Spawn Timing")]
[Tooltip("Minimum interval between spawns (seconds)")]
[SerializeField] private float minSpawnInterval = 1f;
[Tooltip("Maximum interval between spawns (seconds)")]
[SerializeField] private float maxSpawnInterval = 2f;
[Header("Difficulty")]
[Tooltip("Time in seconds for difficulty to ramp from 0 to 1")]
[SerializeField] private float difficultyRampDuration = 60f;
[Tooltip("Curve mapping normalized time (0..1) to difficulty (0..1). Default is linear.")]
[SerializeField] private AnimationCurve difficultyCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
[Tooltip("Maximum jitter applied to computed interval (fractional). 0.1 = +/-10% jitter")]
[SerializeField] private float intervalJitter = 0.05f;
private IBirdPooperSettings settings;
private float spawnTimer;
private bool isSpawning;
private float _currentSpawnInterval = 1f;
// difficulty tracking
private float _elapsedTime = 0f;
internal override void OnManagedAwake()
{
@@ -44,7 +62,7 @@ namespace Minigames.BirdPooper
if (settings == null)
{
Debug.LogError("[ObstacleSpawner] BirdPooperSettings not found!");
return;
// continue — we now use min/max interval fields instead of relying on settings
}
// Validate references
@@ -73,20 +91,56 @@ namespace Minigames.BirdPooper
Debug.LogWarning("[ObstacleSpawner] CameraScreenAdapter not assigned. EdgeAnchor will attempt to auto-find camera.");
}
// Validate interval range
if (minSpawnInterval < 0f) minSpawnInterval = 0f;
if (maxSpawnInterval < 0f) maxSpawnInterval = 0f;
if (minSpawnInterval > maxSpawnInterval)
{
float tmp = minSpawnInterval;
minSpawnInterval = maxSpawnInterval;
maxSpawnInterval = tmp;
Debug.LogWarning("[ObstacleSpawner] minSpawnInterval was greater than maxSpawnInterval. Values were swapped.");
}
// Clamp ramp duration
if (difficultyRampDuration < 0.01f) difficultyRampDuration = 0.01f;
Debug.Log("[ObstacleSpawner] Initialized successfully");
}
private void Update()
{
if (!isSpawning || settings == null || spawnPoint == null) return;
if (!isSpawning || spawnPoint == null) return;
spawnTimer += Time.deltaTime;
_elapsedTime += Time.deltaTime;
if (spawnTimer >= settings.ObstacleSpawnInterval)
if (spawnTimer >= _currentSpawnInterval)
{
SpawnObstacle();
spawnTimer = 0f;
// pick next interval based on difficulty ramp
float t = Mathf.Clamp01(_elapsedTime / difficultyRampDuration);
float difficulty = difficultyCurve.Evaluate(t); // 0..1
// map difficulty to interval: difficulty 0 -> max interval (easy), 1 -> min interval (hard)
float baseInterval = Mathf.Lerp(maxSpawnInterval, minSpawnInterval, difficulty);
// apply small jitter
if (intervalJitter > 0f)
{
float jitter = Random.Range(-intervalJitter, intervalJitter);
_currentSpawnInterval = Mathf.Max(0f, baseInterval * (1f + jitter));
}
else
{
_currentSpawnInterval = baseInterval;
}
// Log the computed interval and difficulty for debugging
Debug.Log($"[ObstacleSpawner] Next spawn interval: {_currentSpawnInterval:F2}s (difficulty {difficulty:F2})");
}
}
@@ -137,10 +191,27 @@ namespace Minigames.BirdPooper
{
isSpawning = true;
spawnTimer = 0f;
_elapsedTime = 0f;
// choose initial interval based on difficulty (at time 0)
float initialDifficulty = difficultyCurve.Evaluate(0f);
float initialBase = Mathf.Lerp(maxSpawnInterval, minSpawnInterval, initialDifficulty);
if (intervalJitter > 0f)
{
float jitter = Random.Range(-intervalJitter, intervalJitter);
_currentSpawnInterval = Mathf.Max(0f, initialBase * (1f + jitter));
}
else
{
_currentSpawnInterval = initialBase;
}
// Log the initial computed interval
Debug.Log($"[ObstacleSpawner] Initial spawn interval: {_currentSpawnInterval:F2}s (difficulty {initialDifficulty:F2})");
// Spawn the first obstacle immediately
SpawnObstacle();
Debug.Log("[ObstacleSpawner] Started spawning (first obstacle spawned immediately)");
}