Простейший способ выбора точки спавна - это дёргать Random.Range до тех пор, пока не получите нужное количество противников.
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
public List<Transform> spawnPoints = new List<Transform>();
public List<GameObject> enemyPrefabs = new List<GameObject>();
public int amountEnemies = 20;
private void Start()
{
SpawnEnemies();
}
public void SpawnEnemies()
{
for (int i = 0; i < amountEnemies; i++)
{
Transform spawnPoint = GetRandomSpawnPoint();
GameObject enemy = SpawnEnemy(spawnPoint);
}
}
private Transform GetRandomSpawnPoint()
{
return spawnPoints[Random.Range(0, spawnPoints.Count)];
}
private GameObject SpawnEnemy(Transform spawnPoint)
{
// Сюда можно дописать использование пула для врагов или более сложный алгоритм выбора противника
var prefab = enemyPrefabs[Random.Range(0, enemyPrefabs.Count)];
return Instantiate(prefab, spawnPoint.position, spawnPoint.rotation);
}
}
Важно понимать, что рандом это рандом, а значит враги будут распределены по всем доступным точкам спавна равномерно, а это не всегда то, что требуется для геймплея. Косвенно плотностью спавна можно управлять добавлением нескольких близких точек, но лучше для этого использовать взвешенный рандом.
public T GetRandom<T>(List<T> list, List<float> weights)
{
if (list == null)
{
throw new ArgumentNullException("list");
}
if (list.Count == 0)
{
throw new ArgumentException("Empty list");
}
if (weights == null)
{
throw new ArgumentNullException("weights");
}
if (weights.Count == 0)
{
throw new ArgumentException("Empty weights");
}
if (list.Count != weights.Count)
{
throw new ArgumentException("List sizes must be equal");
}
if (list.Count == 1)
{
return list[0];
}
var cumulative = new List<float>(weights);
for (int i = 1; i < cumulative.Count; i++)
{
cumulative[i] += cumulative[i - 1];
}
float random = Random.Range(0, cumulative[cumulative.Count - 1]);
int index = cumulative.FindIndex(a => a >= random);
if (index == -1)
{
throw new ArgumentException("Invalid weights");
}
return list[index];
}
Даже со взвешенным рандомом легко может случиться так, что все враги заспавнятся в одном месте, поэтому лучше использовать какой-то алгоритм ротации точек спавна. Для этого можно использовать
Shuffle Bag, либо можно просто выкидывать использованные точки спавна из списка.