99 lines
3.1 KiB
C#
99 lines
3.1 KiB
C#
using System;
|
|
using SepCore.Definition;
|
|
using SepCore.Timer;
|
|
using UnityGameFramework.Runtime;
|
|
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;
|
|
|
|
public void Init(LevelConfig level, Action<EnemyType, int> onSpawn)
|
|
{
|
|
GameEntry.Timer.CancelByOwner(this);
|
|
|
|
_onSpawn = onSpawn;
|
|
int count = level.EnemySpawnConfigs.Count;
|
|
_baseIntervals = new float[count];
|
|
_enemyTypes = new EnemyType[count];
|
|
_spawnCounts = new int[count];
|
|
_elapsedTime = 0f;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var spawnConfig = level.EnemySpawnConfigs[i];
|
|
_baseIntervals[i] = spawnConfig.Interval / 1000f;
|
|
_enemyTypes[i] = spawnConfig.EnemyType;
|
|
_spawnCounts[i] = spawnConfig.EnemyCount;
|
|
}
|
|
|
|
_waveHandles = new TimerHandle[count];
|
|
for (int i = 0; i < count; 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)
|
|
{
|
|
if (_waveHandles == null)
|
|
{
|
|
Log.Error("Can not set spawn rate scale before scheduler init.");
|
|
return;
|
|
}
|
|
|
|
_spawnRateScale = Mathf.Max(MinSpawnRateScale, scale);
|
|
|
|
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(_enemyTypes[waveIndex], _spawnCounts[waveIndex]);
|
|
}
|
|
|
|
private static float GetScaledInterval(float baseInterval, float scale)
|
|
{
|
|
float safeScale = Mathf.Max(MinSpawnRateScale, scale);
|
|
return baseInterval / safeScale;
|
|
}
|
|
}
|
|
}
|