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

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;
}
}
}