Spawn Pooled objects at random spawn locations

Hi, can anyone help me with this issue?

I want my pooled prefabs to spawn on different locations and when the prefab collides with the player, it chooses a different spawn location. I’ve got my pooled objects working somehow. But I can’t get the random position to work. Hope someone can help. Thanks in advance!

My GamePooler script which is attached to an empty gameobject

 public class GamePooler : MonoBehaviour
{
     [System.Serializable]
     public class Pool
     {
         public string tag;
         public GameObject prefab;
         public int size;
     }
     public static GamePooler Instance;
     private void Awake()
     {
         Instance = this;
     }
     public List<Pool> pools;
     public Dictionary<string, Queue<GameObject>> poolDictionary;
     // Start is called before the first frame update
     void Start()
     {
        
         poolDictionary = new Dictionary<string, Queue<GameObject>>();
         foreach(Pool pool in pools)
         {
             Queue<GameObject> objectPool = new Queue<GameObject>();
             for (int i = 0; i < pool.size; i++)
             {
                 GameObject obj = Instantiate(pool.prefab);
                 obj.SetActive(false);
                 objectPool.Enqueue(obj);
             }
             poolDictionary.Add(pool.tag, objectPool);
         }
     }
     public GameObject SpawnFromPool (string tag, Vector3 position, Quaternion rotation)
     {
         if(!poolDictionary.ContainsKey(tag))
         {
             Debug.LogWarning("Pool with tag " + tag + " doesn't exist");
             return null;
         }
         GameObject objectToSpawn = poolDictionary[tag].Dequeue();
         objectToSpawn.SetActive(true);
         objectToSpawn.transform.position = position;
         objectToSpawn.transform.rotation = rotation;
         IPooler pooledObject = objectToSpawn.GetComponent<IPooler>();
         if(pooledObject !=null)
         {
             pooledObject.OnOjectSpawn();
         }
         poolDictionary[tag].Enqueue(objectToSpawn);
         return objectToSpawn;
     }

And my spawner location script

 using System.Collections.Generic;
using UnityEngine;
public class MSpawner : MonoBehaviour
{
     GamePooler moneyPooler;
     public List<Transform> spawnPoints = new List<Transform>();
     // Start is called before the first frame update
     void Start()
     {
         GetSpawnPoints();
         moneyPooler = GamePooler.Instance;
     }
     private void FixedUpdate()
     {
         moneyPooler.SpawnFromPool("Money", RandomSpawnpoint(), Quaternion.identity);
     }
    
     public Vector3 RandomSpawnpoint()
     {
         int randomSP = Random.Range(0, (spawnPoints.Count - 1));
         Vector3 randomSpawnPoint = spawnPoints[randomSP].transform.position;
         return randomSpawnPoint;
     }
     void GetSpawnPoints()
     {
         //List using standar library
         //look through nested children
         Transform[] spList = transform.GetComponentsInChildren<Transform>(); //note: 'this' is not required anymore
         for (int i = 0; i < spList.Length; i++)
         {
             if (spList[i].tag == "SpawnPoints")
             {
                 //add to the list
                 spawnPoints.Add(spList[i]);
             }
         }
     }
}

Can you describe what you mean by the random positions not working? Are they always spawning in the same spot? Are they not spawning at all? Is there an error in the console?

Based on a quick reading of your code I see one error:

int randomSP = Random.Range(0, (spawnPoints.Count - 1));

This should be

int randomSP = Random.Range(0, (spawnPoints.Count));

You don’t need to subtract 1 because the (int, int) overload of Random.Range treats the second parameter as “exclusive”: Unity - Scripting API: Random.Range

Hiya, thanks for getting back to me.

I have tried without " - 1" before.
Basically what’s happening right now is, I have 3 spawn locations (gameobjects with the MSpawner script, 2nd script on my post) and a parent Game object with the Gamepooler script (1st script on my post).

When I enter the game, the money prefab stay put on the spawn locations.
Example - If I set the GamePooler to spawn 2 prefabs, the prefabs will only stay on 2 of the spawn locations and will not disappear when the player collides and will not go onto the 3rd spawn location.

Maybe my question would be, how would I be able to deactivate a prefab after the player collides then get the pooled object to spawn on a different spawn location? And see if that spawn location already has a prefab on it?

Hope that made sense.

Update - I put everything on one script - GamePooler
Still have an issue, I set the script to spawn 1 prefab and now it’s flickering through the 3 spawn locations

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GamePooler : MonoBehaviour
{
    //Inspector Values
    [System.Serializable]
    public class Pool
    {
        public string tag;
        public GameObject prefab;
        public int size;
    }

    public List<Transform> spawnPoints = new List<Transform>();
    public static GamePooler Instance;

    private void Awake()
    {
        Instance = this;
    }
    public List<Pool> pools;
    public Dictionary<string, Queue<GameObject>> poolDictionary;
    // Start is called before the first frame update
    void Start()
    {
        GetSpawnPoints();
        poolDictionary = new Dictionary<string, Queue<GameObject>>();

        //For each pool created
        foreach(Pool pool in pools)
        {
            //Queue objects on that pool
            Queue<GameObject> objectPool = new Queue<GameObject>();

            //Add objects on that queue
            for (int i = 0; i < pool.size; i++)
            {
                GameObject obj = Instantiate(pool.prefab);
                obj.SetActive(false);
                objectPool.Enqueue(obj);
            }

            poolDictionary.Add(pool.tag, objectPool);
        }
    }

    private void FixedUpdate()
    {
        SpawnFromPool("Money", RandomSpawnpoint(), Quaternion.identity);
    }


    public GameObject SpawnFromPool (string tag, Vector3 position, Quaternion rotation)
    {
        //If poolDictionary does not contain the tag assigned on the inspector, then debug
        if(!poolDictionary.ContainsKey(tag))
        {
            Debug.LogWarning("Pool with tag " + tag + " doesn't exist");
            return null;
        }

        //
        GameObject objectToSpawn = poolDictionary[tag].Dequeue();

        objectToSpawn.SetActive(true);
        objectToSpawn.transform.position = position;
        objectToSpawn.transform.rotation = rotation;

        IPooler pooledObject = objectToSpawn.GetComponent<IPooler>();

        if(pooledObject != null)
        {
            pooledObject.OnOjectSpawn();
        }

        poolDictionary[tag].Enqueue(objectToSpawn);

        return objectToSpawn;
    }

    //public method for getting a random Waypoint
    public Vector3 RandomSpawnpoint()
    {
        int randomSP = Random.Range(0, (spawnPoints.Count));
        Vector3 randomSpawnPoint = spawnPoints[randomSP].transform.position;
        return randomSpawnPoint;
    }

    void GetSpawnPoints()
    {
        //List using standard library
        //look through nested children
        Transform[] spList = transform.GetComponentsInChildren<Transform>();
        for (int i = 0; i < spList.Length; i++)
        {
            if (spList[i].tag == "SpawnPoints")
            {
                //add to the list
                spawnPoints.Add(spList[i]);
            }
        }
    }
}