Spawning Prefabs & Arrays(Not Random)

I have some working spawn scripts but got an idea to modify a Random Spawner script from a tutorial which would benefit my game. Basically, I want to remove the randomness from this. I assumed initially that If I put the same amount of enemy prefabs as spawn points there’d be no randomness and each spawn point would initialize an enemy prefab but that didn’t happen.

What I’m looking for is when the trigger is activated my 5 prefabs are instantiated on those 5 spawn points.

public Transform[] spawnPoints;
    public GameObject[] enemyPrefabs;
   
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Enemy_Trigger")) 
        {
              Spawn();
        }
       
    }
       
    private void Spawn()
    {
        int randEnemy = Random.Range(0, enemyPrefabs.Length);
        int randSpawnPoint = Random.Range(0, spawnPoints.Length);

        Pooler.Spawn(enemyPrefabs[0], spawnPoints[randSpawnPoint].position, transform.rotation);
    }

I tried removing the two int lines and gave the value of 0 to spawnPoints instead of randSpawnPoint but that just acted like a single spawner. How can I get each item in both arrays to instantiate when triggerred?

You can use a for() or foreach() loop to iterate an array and do things to it, such as spawn an item at that location.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/statements/iteration-statements

1 Like

Basically, get rid of randSpawnPoint and use the subindexes of the spawn points.
Simple way:

Pooler.Spawn(enemyPrefabs[0], spawnPoints[0].position, transform.rotation);
Pooler.Spawn(enemyPrefabs[0], spawnPoints[1].position, transform.rotation);
Pooler.Spawn(enemyPrefabs[0], spawnPoints[2].position, transform.rotation);
Pooler.Spawn(enemyPrefabs[0], spawnPoints[3].position, transform.rotation);
Pooler.Spawn(enemyPrefabs[0], spawnPoints[4].position, transform.rotation);

Advanced (for adding or removing spawn points later):

for (int i = 0; i < spawnPoints.Length; i++)
{
    Pooler.Spawn(enemyPrefabs[0], spawnPoints[i].position, transform.rotation);
}
1 Like

First off thanks a bunch to both of you. I was messing around with the for and foreach loops and new I was getting close but ran into so many compile issues it wasn’t worthwhile to post. ugh.

Pooler.Spawn(enemyPrefabs[0], spawnPoints[0].position, transform.rotation);
Pooler.Spawn(enemyPrefabs[0], spawnPoints[1].position, transform.rotation);
Pooler.Spawn(enemyPrefabs[0], spawnPoints[2].position, transform.rotation);
Pooler.Spawn(enemyPrefabs[0], spawnPoints[3].position, transform.rotation);
Pooler.Spawn(enemyPrefabs[0], spawnPoints[4].position, transform.rotation);

I came up with this solution yesterday. It works fine. However, I wanted to have one script deal with all this and not make a 5, 10, ect version. I did test that I can make it spawn 3 objects but if my arrays are only 2 objects, it still just spawns the two.

I wanted to use the loop because I just want one script and this is where Kiel814 saved my sanity. I was getting the for loop right but not the instantiation of the array. Putting “i” instead of “0” helped me out. This is what I came up with and it works fine for my needs. Since I wanted to have different enemies in the array i needed to loop through a 2nd one.

for (int i = 0; i < spawnPoints.Length; i++)
        {
            for (int g = 0; g < enemyPrefabs.Length; g++)
            {
                Pooler.Spawn(enemyPrefabs[i], spawnPoints[i].position, transform.rotation);
            }
 }

But, I have a question. If my spawnPoints For loop has a variable of “i” I obviously had to pick another letter, “g” for my nested enemy loop. Why is it when I put “g” in enemyPrefabs[ ] the spawning is wrong but when I leave it with the “i” works perfectly. Why does this line not spawn correctly but the above does?

Pooler.Spawn(enemyPrefabs[g], spawnPoints[i].position, transform.rotation);

Not quite. The code you have above will put copies of EVERY enemy at EVERY spawnpoint. That’s not likely what you want.

Instead, you want to ONLY iterate all your spawnpoints, then choose (Each time) what kind of single enemy to place at each spawnpoint.

“Choose” could mean:

  • always put the first one (what you did with [0])

  • cycle through available enemies (keep an index into prefabs, increase it, and when it exceeds .Length, wrap it back to zero)

  • randomly choose available enemies (pick the enemy prefab index as Random.Range( 0, enemyPrefabs.Length);)

  • some other way perhaps?

1 Like

Alright. I NOW see what you mean. When I tested this earlier this earlier this morning before I went golfing I did not notice that my score for each enemy that was destroyed was 300 instead of 100, because when I looked right now at the pooling I had 3 enemies on each spawn point like you said. I’m back to the following now:

private void Spawn()
    {
           
        for (int i = 0; i < spawnPoints.Length; i++)
        {
        Pooler.Spawn(enemyPrefabs[0], spawnPoints[i].position, transform.rotation);
        }
    }

This will work for now with for the majority of my needs.

Selecting randomly from a collection of GameObjects is so common that I have a little helper ScriptableObject I call GameObjectCollection.

You would make one for each “gathering” of things, like

Level1Enemies
Level2Enemies
FlyingEnemies
EnemyTanks

etc.

Full code:

You could use it to pick shuffled items from a collection for all kinds of purposes, such as spawning above.