hel with object pooling?

Hi everyone!

I have two scripts; one for object pooling and another which pulls the objects from the pool (no pun intended) and creates a grid. the scripts work, and the grid is created as I would like. Where I am stuck however is creating a pool which consists of various different objects and then having the specific object pulled based on a particular condition.
The objects in the pool are circles and squares. I have code on the circles which will deactivate the gameobject and change a static int variable called “item” to “2” when tapped with the OnMouseDownAsButton function.
I want to create a script where the object taken from the pool will be the circle when the item variable is set to 1, and a square when the item variable is set to two. I am completely stumped as to how to get this done. Can someone assist with this script?

please take a look at the scripts I have generated thus far:

object pooler script :

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

[System.Serializable]
public class ObjectPoolItem
{
    public int amountToPool;
    public GameObject objectToPool;
    public bool shouldExpand;
}

public class ObjectPooler : MonoBehaviour {
    public static ObjectPooler SharedInstance;
    public List<GameObject> pooledObjects;
    public List<ObjectPoolItem> itemsToPool;

    void Awake()
    {
        SharedInstance = this;
    }

    // Use this for initialization
    void Start()
    {
        pooledObjects = new List<GameObject>();
        foreach (ObjectPoolItem item in itemsToPool)
        {
            for (int i = 0; i < item.amountToPool; i++)
            {
                GameObject obj = (GameObject)Instantiate(item.objectToPool);
                obj.SetActive(false);
                pooledObjects.Add(obj);
            }
        }
    }

    public GameObject GetPooledObject(string tag)
    {
        for (int i = 0; i < pooledObjects.Count; i++)
        {
            if (!pooledObjects_.activeInHierarchy && pooledObjects*.tag == tag)*_

{
return pooledObjects*;*
}
}
foreach (ObjectPoolItem item in itemsToPool)
{
if (item.objectToPool.tag == tag)
{
if (item.shouldExpand)
{
GameObject obj = (GameObject)Instantiate(item.objectToPool);
obj.SetActive(false);
pooledObjects.Add(obj);
return obj;
}
}
}
return null;
}
}

Grid script:
public List circles = new List();
public List circles1 = new List();
public static Vector3 positions = new Vector3();
public int gridheight = 4;
public int gridwidth = 4;
public static bool on = false;
public bool on1 = false;
public GameObject self;

void Start()
{
StartCoroutine(Spawn1());
gameObject.transform.position = new Vector3(-5.1f, -4.74f, 0);
}

void Update()
{
on1 = on;
if (statics.playagain == false)
{
Destroy(self);
}
if (circles1.Count < 16)
{
foreach (GameObject a in circles)
{
circles1.Add(a.transform.position);
}
}
foreach (GameObject b in circles)
{
if (!b.activeSelf)
{
StartCoroutine(ReSpawn(b));
}
}
}

IEnumerator Spawn1()
{
yield return new WaitForSeconds(0.1f);
for (var y = 0; y < gridheight; y++)
{
for (var x = 0; x < gridwidth; x++)
{
GameObject g = ObjectPooler.SharedInstance.GetPooledObject(“black1”);
if (g != null)
{
g.transform.position = new Vector3(x - 1.47f, y - 1.41f, 0);
g.transform.parent = gameObject.transform;
g.SetActive(true);
}
circles.Add(g);
}
}
}

IEnumerator ReSpawn(GameObject target)
{
yield return new WaitForSeconds(5f);
target.SetActive(true);
}
can anyone assist with this? It will be greatly appreciated!

You could use a dictionary with a generic value where the key is your tag.
It will then retrieve the generic value (which can be whatever kind of object you like) by the given tag. That way you can put in your object pool whatever you want.

Something like:

Dictionary<string, TValue> pooledObjects = new Dictionary<string, TValue>();
pooledObjects.Add("circel", circelObject); //circelObject can be anything
pooledObjects.Add("square", squareObject); //squareObject can be anything

Well, a single pool is ment to represent cached versions of a single item. It doesn’t make much sense to put different types into a single pool. You either have to:

  • Make your pool class “instantiable” (i.e. no static stuff) and create seperate instances of that class, one for each object type.
  • Change your pool class to actually contain multiple pools

It seems that your “ObjectPoolItem” is actually what represents a single type of object. So simply implement your pool in there. You also might want to use two seperate lists for each pool. One active list and one pool list. When you request an object from the pool you simply grab one object from the pool, remove it from the pool list and move it to your active list. Just keep going until you run out of objects in your pool list. If the pool list is empty you do a single run through your “active list” and move the inactive objects back to the pool list.

Here’s an example:

[System.Serializable]
public class ObjectPoolItem
{
    public int amountToPool;
    public GameObject objectToPool;
    public bool shouldExpand;
    [NonSerialized]
    public Stack<GameObject> pool = new Stack<GameObject>();
    [NonSerialized]
    public List<GameObject> active = new List<GameObject>();
    public GameObject Get()
    {
        if (pool.Count > 0)
        {
            var obj = pool.Pop();
            active.Add(obj);
            return obj;
        }
        for (int i = active.Count - 1; i >= 0; i--)
        {
            if (!active*.activeInHierarchy)*

{
pool.Push(active*);*
active.RemoveAt(i);
}
}
if (pool.Count > 0)
{
var obj = pool.Pop();
active.Add(obj);
return obj;
}
/* no objects left instantiate a new object or return null*/
if (shouldExpand)
{
var obj = UnityEngine.Object.Instantiate(objectToPool);
active.Add(obj);
return obj;
}
return null;
}
public void Init()
{
for (int i = 0; i < amountToPool; i++)
{
pool.Push(UnityEngine.Object.Instantiate(objectToPool));
pool.Peek().SetActive(false);
}
}

}

public class ObjectPooler : MonoBehaviour
{
public static ObjectPooler SharedInstance;
public List itemsToPool;
private Dictionary<string, ObjectPoolItem> m_Lookup = new Dictionary<string, ObjectPoolItem>();

void Awake()
{
SharedInstance = this;
}

// Use this for initialization
void Start()
{
m_Lookup.Clear();
foreach (ObjectPoolItem item in itemsToPool)
{
item.Init();
m_Lookup.Add(item.objectToPool.tag, item);
}
}

public GameObject GetPooledObject(string tag)
{
ObjectPoolItem item;
if (m_Lookup.TryGetValue(tag, out item))
{
return item.Get();
}
Debug.LogWarning("No pooled object with tag: " + tag);
return null;
}
}
Each “ObjectPoolItem” basically is a seperate pool. The “ObjectPooler” class just manages multiple ObjectPoolItems and uses a dictionary to speed up the tag lookup. Since each ObjectPoolItem only contains a single type of object it’s easier to maintain the pool.