Cant get my item Pool to work proplery..

Hey guys ive been trying to create a pool for my obstacles that spawn in front of the player in an endless runner. So i tried creating a simple pooling system so its not constantly instantiating and destroying, but ive kinda hit the road block with it. atm im using a simple click to activate and right click to deactivate to test, but when i right click it deactivates all the objects but doesnt add them all to the inactive list correctly. for example sometimes it adds only 1 of the objects 3 times.

This goes on the object,
 
public class pooledObj : MonoBehaviour 
{
 
    void Update () 
    {
       if(Input.GetMouseButtonDown(1))
       {
         Deactivate();
       }
 
    }
    void Deactivate()
    {
       gameObject.SetActive(false);
       transform.position = Vector3.zero;
       objPool.objPoolSelf.DeactivateObject();
 
    }
 
}
 
This goes on a manager gameobject
public class objPool : MonoBehaviour 
{
    public  List<GameObject> prefabs = new List<GameObject>();
    public  List<GameObject> prefabPoolInactive = new List<GameObject>();
    public     List<GameObject> prefabPoolActive = new List<GameObject>();
    public GameObject tempPool;
    public static objPool objPoolSelf;
    //public int numberOfPrefabs = 0;
 
 
    void Awake()
    {
       objPoolSelf = this;
    }
 
    // Use this for initialization
    void Start () 
    {
       for (int i = 0; i < prefabs.Count; i++)
       {
         prefabPoolInactive.Add((GameObject)Instantiate(prefabs[i])); 
         prefabPoolInactive[i].SetActive(false); 
       }
    }
    void ActivateObject()
    {
       for (int  i = 0; i < prefabs.Count; i++)
       {
         if (prefabPoolInactive[i].active == false)
         {
          tempPool = prefabPoolInactive[Random.Range(0, prefabPoolInactive.Count)];
          tempPool.SetActive(true);
          prefabPoolActive.Add(tempPool);
          prefabPoolInactive.Remove(tempPool);
          return;
 
         }
       }
 
    }
 
    public void DeactivateObject()
    {
       prefabPoolInactive.Add(tempPool);
       prefabPoolActive.Remove(tempPool);
    }
 
    // Update is called once per frame
    void Update () 
    {
       if(Input.GetMouseButtonDown(0))
       {
         ActivateObject();
       }
 
    }
}

Is it also possible to add more than 1 of each prefab the list when instantiated so i have more than 1 of the object to activate?

So eventually what i want to do is pick a random object from the inactive list place it infront of the player and put it in the active list, once its behind the player, deactivate it and put it back in the inactive list, pretty much rinse and repeat. The main reason i started doing this was because i wanted to randomly pick one from the list of objects most of the other pooling examples ive seen only has 1 object and cant pick randomly from it.

Anyway any help would be appreciated and thanks for reading.

PS im very new to programming this is as far as i got without help.

When deactivating, the “pooledObj” should pass a reference to itself so “objPool” knows which object it’s about. The “tempPool” reference is only the last activated object, and you shouldn’t use that.

My Runner tutorial uses a queue to reuse platforms for a simple endless runner game. While it doesn’t reuse objects at random, it randomizes their configuration on reuse.

Hey thanks for the reply, Ive seen your tutorial and it was very helpful. The reason i use a list of different prefabs is because they will have different models which is why im not randomizing the way you are in your tutorial. Your tutorial is awesome if i could use the way you do the platforms with random prefabs it would solve all my problems :stuck_out_tongue:

If you want to have a fixed chance of spawning any type of object, you want to keep them separate instead of mixing them in one pool. Otherwise what you get depends on what’s currently not being used. And instead of pre-instantiating, you can do the lazy approach and only instantiate whenever you have nothing to reuse. That way you can never run out of objects. Below is a quick example based on your approach that does this.

using UnityEngine;

public class PooledObject : MonoBehaviour {

	public int prefabIndex;
	public ObjectPool pool;

	void OnEnable () {
		// Randomize on each activation.
		transform.localPosition = Random.insideUnitSphere * 2f;
		transform.localRotation = Random.rotation;
	}

	void OnMouseDown () {
		Deactivate();
	}

	private void Deactivate () {
		pool.Reclaim(this);
	}

}
using UnityEngine;
using System.Collections.Generic;

public class ObjectPool : MonoBehaviour {

	public List<PooledObject> prefabs;

	private List<Stack<GameObject>> pools;

	void Start () {
		pools = new List<Stack<GameObject>>(prefabs.Count);
		for (int i = 0; i < prefabs.Count; i++) {
			pools.Add(new Stack<GameObject>());
		}
	}

	void Update () {
		if (Input.GetKeyDown(KeyCode.S)) {
			SpawnObject();
		}
	}

	private void SpawnObject () {
		// Select prefab type to spawn.
		int prefabIndex = Random.Range(0, pools.Count);

		if (pools[prefabIndex].Count > 0) {
			// Reuse existing instance.
			pools[prefabIndex].Pop().SetActive(true);
			Debug.Log("Reused instance of type " + prefabIndex);
		}
		else {
			// Create new instance.
			PooledObject o = (Instantiate(prefabs[prefabIndex]) as PooledObject);
			o.prefabIndex = prefabIndex;
			o.pool = this;
			// Make child of pool to keep hierarchy clean.
			o.transform.parent = transform;
			Debug.Log("Instantiated new instance of type " + prefabIndex);
		}
	}

	public void Reclaim (PooledObject o) {
		o.gameObject.SetActive(false);
		pools[o.prefabIndex].Push(o.gameObject);
		Debug.Log("Reclaimed instance of type " + o.prefabIndex);
	}
}

Configure some prefabs, then spawn them with the “s” key and deactivate the instances by clicking on them (they need to have colliders).

Thanks! ill def try this out, instantiating it like this wont be too slow on mobile devices right?

It’s fine for mobile devices. I used the same sort of lazy pooling approach for everything in this old game that ran perfectly on the 1st generation iPod Touch.

Awesome thanks for the help :slight_smile: