How to reduce the chances of a particular enemy spawning ?

I have an array of enemy prefabs inside which, I’m adding the different kinds of enemies I want it to spawn. Currently it spawns any enemy it wants to and there is no control over how many times I want a particular enemy to spawn. How do I make it so that a particular enemy spawns rarely ? Here is my current code:

	public float spawnTime = 5f;		// The amount of time between each spawn.
	public float spawnDelay = 3f;		// The amount of time before spawning starts.
	public GameObject[] enemies;		// Array of enemy prefabs.
	
	void Start ()
	{
		// Start calling the Spawn function repeatedly after a delay .
		InvokeRepeating("Spawn", spawnDelay, spawnTime);
	}
	
	void Spawn ()
	{
		// Instantiate a random enemy.
		int enemyIndex = Random.Range(0, enemies.Length);
		Instantiate(enemies[enemyIndex], transform.position, transform.rotation);
	}

You could base it off chance.
The example below has a 50/50 chance of spawning.

float rand = Random.Range(0, 101);
    
if (rand >= 50) {
    // spawn enemy //
}

for more rarity you could make the enemy spawn with a 5% chance:

float rand = Random.Range(0, 101);
    
if (rand >= 95) {
    // spawn enemy //
}

hope it helps :stuck_out_tongue:

One possible approach is to add a variable to the class enemy for counting the times that an enemy is selected by the random before spawn it. For example:

CommonEnemy.counterToNextSpawn=1;
RareEnemy.counterToNextSpawn=10;

int enemyIndex = Random.Range(0, enemies.Length);
enemy selectedEnemy = enemies[enemyIndex] as enemy;
selectedEnemy.counterToNextSpawn-=1;
    
if(selectedEnemy.counterToNextSpawn==0)
{
   // Initializes the couter to its original value (it depends of the type of the enemy)
   selectedEnemy.counterToNextSpawn=1;  
   Instantiate(enemies[enemyIndex], transform.position, transform.rotation);
}

This way an enemy only will be spawned when its counterToNextSpawn is equal to 0: common enemies will spawn each time the random points them, rare enemies will need 10 hits of the random function to spawn. You can make a gradient with the counter values or whatever you need, this is just an approach :slight_smile:

Managed to get some help off Reddit. Here is a modified version of my previous code to have a chance based spawn of a particular enemy.

public float spawnTime = 5f; // The amount of time between each spawn.
public float spawnDelay = 3f; // The amount of time before spawning starts.
public float chanceSpawnRare = 0.1f; // Chance that a rare enemy will spawn.
public GameObject[] normalEnemies; // Array of regular enemy prefabs.
public GameObject[] rareEnemies; // Array of the rare enemy prefabs.

void Start ()
{
    // Start calling the Spawn function repeatedly after a delay.
    InvokeRepeating("Spawn", spawnDelay, spawnTime);
}

GameObject[] spawnArray;
int enemyIndex;

void Spawn ()
{
    // Chance to spawn rare, or normal enemies.
    if(Random.Range(0f, 1f) > chanceSpawnRare)
    {
        spawnArray = normalEnemies;
    }
    else
    {
        spawnArray = rareEnemies;
    }

    // Instantiate an enemy.
    enemyIndex = Random.Range(0, spawnArray.Length);
    Instantiate(spawnArray[enemyIndex], transform.position, transform.rotation);
}