using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class ObjectPool : MonoBehaviour
{
public static ObjectPool instance;
/// <summary>
/// The object prefabs which the pool can handle.
/// </summary>
public GameObject[] objectPrefabs;
/// <summary>
/// The pooled objects currently available.
/// </summary>
public List<GameObject>[] pooledObjects;
/// <summary>
/// The amount of objects of each type to buffer.
/// </summary>
public int[] amountToBuffer;
public int defaultBufferAmount = 3;
/// <summary>
/// The container object that we will keep unused pooled objects so we dont clog up the editor with objects.
/// </summary>
protected GameObject poolContainer;
/// <summary>
/// The container object that we will keep active objects so we dont clog up the editor with objects.
/// </summary>
protected GameObject activeObjectsContainer;
void Awake()
{
instance = this;
}
// Use this for initialization
void Start()
{
poolContainer = new GameObject("ObjectPool");
activeObjectsContainer = new GameObject("ActiveObjectsContainer");
//Loop through the object prefabs and make a new list for each one.
//We do this because the pool can only support prefabs set to it in the editor,
//so we can assume the lists of pooled objects are in the same order as object prefabs in the array
pooledObjects = new List<GameObject>[objectPrefabs.Length];
int i = 0;
foreach (GameObject objectPrefab in objectPrefabs)
{
pooledObjects[i] = new List<GameObject>();
int bufferAmount;
if (i < amountToBuffer.Length) bufferAmount = amountToBuffer[i];
else
bufferAmount = defaultBufferAmount;
for (int n = 0; n < bufferAmount; n++)
{
GameObject newObj = Instantiate(objectPrefab);
newObj.name = objectPrefab.name;
PoolObject(newObj);
}
i++;
}
}
/// <summary>
/// Gets a new object for the name type provided. If no object type exists or if onlypooled is true and there is no objects of that type in the pool
/// then null will be returned.
/// </summary>
/// <returns>
/// The object for type.
/// </returns>
/// <param name='prefabName'>
/// Object type.
/// </param>
/// <param name='allowGrow'>
/// If true, it will only return an object if there is one currently pooled.
/// </param>
public GameObject GetObjectForType(string prefabName, bool allowGrow)
{
for (int i = 0; i < objectPrefabs.Length; i++)
{
GameObject prefab = objectPrefabs[i];
if (prefab.name == prefabName)
{
if (pooledObjects[i].Count > 0)
{
GameObject pooledObject = pooledObjects[i][0];
pooledObjects[i].RemoveAt(0);
pooledObject.transform.parent = activeObjectsContainer.transform;
pooledObject.SetActive(true);
return pooledObject;
}
else if (allowGrow)
{
GameObject newObj = Instantiate(prefab);
newObj.name = prefab.name;
newObj.transform.parent = activeObjectsContainer.transform;
return newObj;
}
break;
}
}
//If we have gotten here either there was no object of the specified type or non were left in the pool with onlyPooled set to true
return null;
}
/// <summary>
/// Gets a new objectby the prefabIndex provided. If no object type exists or if onlypooled is true and there is no objects of that type in the pool
/// then null will be returned.
/// </summary>
/// <returns>
/// The object for type.
/// </returns>
/// <param name='prefabName'>
/// Object type.
/// </param>
/// <param name='allowGrowth'>
/// If true, it will only return an object if there is one currently pooled.
/// </param>
public GameObject GetObjectAtIndexPrefab(int prefabIndex, bool allowGrowth)
{
if (prefabIndex >= objectPrefabs.Length)
{
Debug.LogError("Tryed to Instantiate prebad at Index"+ prefabIndex + "objects prefab size: " + objectPrefabs.Length);
return null;
}
GameObject prefab = objectPrefabs[prefabIndex];
if (pooledObjects[prefabIndex].Count > 0)
{
GameObject pooledObject = pooledObjects[prefabIndex][0];
pooledObjects[prefabIndex].RemoveAt(0);
pooledObject.transform.parent = activeObjectsContainer.transform;
pooledObject.SetActive(true);
return pooledObject;
}
else if (allowGrowth)
{
GameObject newObj = Instantiate(prefab) as GameObject;
newObj.name = prefab.name;
newObj.transform.parent = activeObjectsContainer.transform;
return newObj;
}
//If we have gotten here either there was no object of the specified type or non were left in the pool with onlyPooled set to true
return null;
}
/// <summary>
/// Pools the object specified. Will not be pooled if there is no prefab of that type.
/// </summary>
/// <param name='obj'>
/// Object to be pooled.
/// </param>
public void PoolObject(GameObject obj)
{
for (int i = 0; i < objectPrefabs.Length; i++)
{
if (objectPrefabs[i].name == obj.name)
{
obj.SetActive(false);
obj.transform.parent = poolContainer.transform;
pooledObjects[i].Add(obj);
return;
}
}
}
/// <summary>
/// Returns the length of the Object Prefabs
/// </summary>
/// <returns>objectPrefabs.Length</returns>
internal int GetObjectsPrefabLength()
{
return objectPrefabs.Length;
}
}