You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
4.8 KiB
153 lines
4.8 KiB
/* |
|
* Unless otherwise licensed, this file cannot be copied or redistributed in any format without the explicit consent of the author. |
|
* (c) Preet Kamal Singh Minhas, http://marchingbytes.com |
|
* contact@marchingbytes.com |
|
*/ |
|
// modified version by Kanglai Qian |
|
using UnityEngine; |
|
using System.Collections.Generic; |
|
|
|
namespace ET.Util |
|
{ |
|
public enum PoolInflationType |
|
{ |
|
/// When a dynamic pool inflates, add one to the pool. |
|
INCREMENT, |
|
/// When a dynamic pool inflates, double the size of the pool |
|
DOUBLE |
|
} |
|
|
|
public class GameObjectPool |
|
{ |
|
private Stack<PoolObject> availableObjStack = new Stack<PoolObject>(); |
|
|
|
//the root obj for unused obj |
|
private GameObject rootObj; |
|
private PoolInflationType inflationType; |
|
private string poolName; |
|
private int objectsInUse = 0; |
|
|
|
public GameObjectPool(string poolName, GameObject poolObjectPrefab, GameObject rootPoolObj, int initialCount, PoolInflationType type) |
|
{ |
|
if (poolObjectPrefab == null) |
|
{ |
|
#if UNITY_EDITOR |
|
Debug.LogError("[ObjPoolManager] null pool object prefab !"); |
|
#endif |
|
return; |
|
} |
|
this.poolName = poolName; |
|
this.inflationType = type; |
|
this.rootObj = new GameObject(poolName + "Pool"); |
|
this.rootObj.transform.SetParent(rootPoolObj.transform, false); |
|
|
|
// In case the origin one is Destroyed, we should keep at least one |
|
GameObject go = GameObject.Instantiate(poolObjectPrefab); |
|
PoolObject po = go.GetComponent<PoolObject>(); |
|
if (po == null) |
|
{ |
|
po = go.AddComponent<PoolObject>(); |
|
} |
|
po.poolName = poolName; |
|
AddObjectToPool(po); |
|
|
|
//populate the pool |
|
populatePool(Mathf.Max(initialCount, 1)); |
|
} |
|
|
|
//o(1) |
|
private void AddObjectToPool(PoolObject po) |
|
{ |
|
//add to pool |
|
po.gameObject.SetActive(false); |
|
po.gameObject.name = poolName; |
|
availableObjStack.Push(po); |
|
po.isPooled = true; |
|
//add to a root obj |
|
po.gameObject.transform.SetParent(rootObj.transform, false); |
|
} |
|
|
|
private void populatePool(int initialCount) |
|
{ |
|
for (int index = 0; index < initialCount; index++) |
|
{ |
|
PoolObject po = GameObject.Instantiate(availableObjStack.Peek()); |
|
AddObjectToPool(po); |
|
|
|
} |
|
} |
|
|
|
//o(1) |
|
public GameObject GetAvailableObject(bool autoActive = true) |
|
{ |
|
PoolObject po = null; |
|
if (availableObjStack.Count > 1) |
|
{ |
|
po = availableObjStack.Pop(); |
|
} |
|
else |
|
{ |
|
int increaseSize = 0; |
|
//increment size var, this is for info purpose only |
|
if (inflationType == PoolInflationType.INCREMENT) |
|
{ |
|
increaseSize = 1; |
|
} |
|
else if (inflationType == PoolInflationType.DOUBLE) |
|
{ |
|
increaseSize = availableObjStack.Count + Mathf.Max(objectsInUse, 0); |
|
} |
|
#if UNITY_EDITOR |
|
Debug.Log(string.Format("Growing pool {0}: {1} populated", poolName, increaseSize)); |
|
#endif |
|
if (increaseSize > 0) |
|
{ |
|
populatePool(increaseSize); |
|
po = availableObjStack.Pop(); |
|
} |
|
} |
|
|
|
GameObject result = null; |
|
if (po != null) |
|
{ |
|
objectsInUse++; |
|
po.isPooled = false; |
|
result = po.gameObject; |
|
if (autoActive) |
|
{ |
|
result.SetActive(true); |
|
} |
|
} |
|
|
|
return result; |
|
} |
|
|
|
|
|
|
|
//o(1) |
|
public void ReturnObjectToPool(PoolObject po) |
|
{ |
|
if (poolName.Equals(po.poolName)) |
|
{ |
|
objectsInUse--; |
|
/* we could have used availableObjStack.Contains(po) to check if this object is in pool. |
|
* While that would have been more robust, it would have made this method O(n) |
|
*/ |
|
if (po.isPooled) |
|
{ |
|
#if UNITY_EDITOR |
|
Debug.LogWarning(po.gameObject.name + " is already in pool. Why are you trying to return it again? Check usage."); |
|
#endif |
|
} |
|
else |
|
{ |
|
AddObjectToPool(po); |
|
} |
|
} |
|
else |
|
{ |
|
Debug.LogError(string.Format("Trying to add object to incorrect pool {0} {1}", po.poolName, poolName)); |
|
} |
|
} |
|
} |
|
} |