у вас было несколько ошибок в вашей логике c, я реорганизовал ваш код в качестве сопрограммы, так как я думаю, что он более уместен в вашем случае.
StartCoroutine(SpawnEnemies());
}
public IEnumerator SpawnEnemies()
{
while (_spawnedEnemies < _enemiesToSpawn.OrderBy(o => Random.value))
{
// You should really store these "magic numbers" in variables (5.4f)
yield return new WaitForSeconds(5.4f);
foreach (var spawnPoint in _spawnPoints)
{
var cols = Physics.OverlapSphere(spawnPoint.transform.position, EnemyRadius);
// I would recommend not using tags in general, instead maybe GetComponent<AIController>() or even better, use an enemy layer and use a mask when overlapping the sphere
if (cols.Any(c => c.tag == "AI Controller"))
{
continue;
}
Instantiate(_enemyPrefab, spawnPoint.position, spawnPoint.rotation);
currentEnemy++;
break;
}
}
}
По сути, функция управляет своим жизненным циклом по сравнению с ... используя invoke, он выполняет итерацию по всем точкам вызова, проверяет, есть ли там какие-либо контроллеры ИИ, и, если нет, порождает там врага.
Если все точки вызова заняты, функция будет ожидать заданную задержку ( 5.4s), а затем повторите попытку.
_enemiesToSpawn.OrderBy(o => Random.value)
- это быстрое перемешивание в точках низкой производительности (в вашем случае это будет вызываться N раз каждые 5,4 секунды, что незначительно)
Вы Вы также можете перемещать урожай после за l oop, таким образом, вы сначала будете вызывать врага без задержки и только потом ждать следующего появления.