Object Pooling for Prefab Spawners

using Random = System.Random; 
// I dont normally use Unitys Random function prefer the C# Random

public class SpawnerScript
{
	public GameObject prefabtospawn;
	
	int initialSpawnAmount = 15; //An arbitrary spawn amount
	
	const String empty="Empty";
	
	//Using an Object Pool to efficiently handle the spawned prefabs
	
	List<GameObject> prefabslist;
	
	/*
	Suppose you have multiple objects you can do this
	
	public GameObject[] prefabstospawn;
	List<List<GameObject>> spawnedprefabslists = new List<List<GameObject>>();
	
	Then Inside Awake 
        for(int i=0;objectstospawn.Length;i++)
        spawnedprefabslists.Add(new List<GameObject>());	
	*/
	static readonly Vector3 vectorzero = Vector3.zero;
	static readonly Quaternion rotationzero = Quaternion.identity;
	
	static SpawnerScript thisscript;
	static bool spawn = true;
	
	void Awake()
	{
		thisscript = this;
	
		if(prefabtospawn==null)
		{
			Debug.Log("prefabtospawn variable is empty");
			prefabtospawn = new GameObject("Empty");
		}
		
		initializeObjectPool();
	}
	
	static bool toggleSpawn()
	{
		spawn = !spawn;
	}
	
	static SpawnerScript returnme()
	{
	return this; 
        //Using this to access the IEnumerator periodicSpawn 
        //E.g. SpawnerScript.returnme().StartCoroutine("periodicSpawn");
	}
	void initializeObjectPool()
	{
	   prefabslist = new List<GameObject>();
	
	   for(int i =0;i<initialSpawnAmount;i++)
	   {
	      spawnedobjectslist.Add(GameObject.Instantiate(objecttospawn, vectorzero,rotationzero).SetActive(false));
	    //I normally deactivate the spawned objects by default
	   }
	}
	
	
	void spawnPrefab(Vector3 pos, Quaternion rot) 
        // The pos and rot parameters are used to initialize the position and rotation of the spawned GameObject
	{
		for(int i=0;i<prefabslist.Count;i++)
		{
			if(!prefabslist[i].activeInHierarchy) //If the gameObject is currently not active in the scene we 'spawn' it
			{
				prefabslist.transform.position = pos;
				prefabslist.transform.rotation = rot;
		            // depends on how you wish to use this you can either put this return type as GameObject 
                            //or just do a return after setting it to active I use the latter in this case;
				prefabslist[i].SetActive(true);
				return;
			}
		}
		
		spawnedobjectslist.Add(GameObject.Instantiate(objecttospawn, pos,rot).SetActive(true)); // In case your prefab was set to disabled by default
	}
	
	float frequency=0.05f; 
	
	IEnumerator periodicSpawn()
	{
		while(true)
		{
			yield return new WaitForSeconds(frequency);
			
			if(spawn)
			{
			     spawnPrefab(Vector3, Quaternion); 
                             //Just use some random method to randomise position, rotation can just set to Quaternion.identity 
			     Random rand = new Random(Guid.NewGuid().GetHashCode());
                            // The reason why I prefer the C# Random, this creates a new seed for the Random.Next() method
	                    //E.g. new Vector3(rand.Next(int,int),rand.Next(int,int),rand.Next(int,int)); ///SuperScript here ///
			}
		}
	}
}
  • I normally dont destroy my objects because of tricky coupling that might occur elsewhere usually i just (Deactivate their Functions First -> Reset their relevant paramters -> Deactivate the Object)
  • Awake & Start only run once in the lifetime of the script so you cant depend on it to reset your spawned prefabs parameters.
  • Thus respawning logic gets returned back to this script
  • Two methods of spawning can be used either use FixedUpdate/Update or use an Enumerator Im using an Enumerator in this case

-> Random Seed function
-> Unity Live Session On Object Pooling