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
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?
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]);
}
}
}
}