vampire-like/Assets/GameMain/Scripts/Runtime/CustomComponent/EnemyManager/EnemySpawnScheduler.cs

85 lines
2.6 KiB
C#

using System;
using SepCore.DataTable;
using SepCore.Definition;
using SepCore.Timer;
using UnityEngine;
namespace SepCore.EnemyManager
{
public class EnemySpawnScheduler
{
private const float MinSpawnRateScale = 0.1f;
private float _elapsedTime;
private float[] _baseIntervals;
private EnemyType[] _enemyTypes;
private int[] _spawnCounts;
private TimerHandle[] _waveHandles;
private float _spawnRateScale = 1f;
private Action<EnemyType, int> _onSpawn;
public float SpawnRateScale => _spawnRateScale;
public float ElapsedTime => _elapsedTime;
public int WaveCount => _enemyTypes?.Length ?? 0;
public void Init(DRLevel level, Action<EnemyType, int> onSpawn)
{
GameEntry.Timer.CancelByOwner(this);
_onSpawn = onSpawn;
_baseIntervals = (float[])level.Intervals.Clone();
_enemyTypes = level.EntityTypes;
_spawnCounts = level.EntityCounts;
_elapsedTime = 0f;
_waveHandles = new TimerHandle[_baseIntervals.Length];
for (int i = 0; i < _baseIntervals.Length; i++)
{
int waveIndex = i;
float interval = GetScaledInterval(_baseIntervals[i], _spawnRateScale);
_waveHandles[i] = GameEntry.Timer.ScheduleRepeat(interval, () => OnWaveTick(waveIndex), -1, this);
}
}
public void Tick(float deltaTime)
{
_elapsedTime += deltaTime;
}
public void SetSpawnRateScale(float scale)
{
_spawnRateScale = Mathf.Max(MinSpawnRateScale, scale);
if (_waveHandles == null) return;
for (int i = 0; i < _waveHandles.Length; i++)
{
float newInterval = GetScaledInterval(_baseIntervals[i], _spawnRateScale);
GameEntry.Timer.SetInterval(_waveHandles[i], newInterval, adjustRemainingTime: true);
}
}
public void Reset()
{
GameEntry.Timer.CancelByOwner(this);
_elapsedTime = 0;
_baseIntervals = null;
_enemyTypes = null;
_spawnCounts = null;
_waveHandles = null;
_spawnRateScale = 1f;
_onSpawn = null;
}
private void OnWaveTick(int waveIndex)
{
_onSpawn?.Invoke(_enemyTypes[waveIndex], _spawnCounts[waveIndex]);
}
private static float GetScaledInterval(float baseInterval, float scale)
{
float safeScale = Mathf.Max(MinSpawnRateScale, scale);
return baseInterval / safeScale;
}
}
}