ProjectCreep/Assets/TBTK/Scripts/Misc/ObjectPoolManager.cs

214 lines
5.5 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ObjectPoolManager : MonoBehaviour{
private static bool disablePooling=false;
public bool showUninitiatedPoolWarning=false;
public List<Pool> poolList=new List<Pool>();
public static ObjectPoolManager instance;
void Awake(){
if(instance!=null && instance!=this){
Debug.Log("Error, there are multiple instance of ObjectPoolManager in the scene");
return;
}
instance=this;
}
public static void Init(){
if(instance!=null) return;
instance=(ObjectPoolManager)FindObjectOfType(typeof(ObjectPoolManager));
if(instance==null){
GameObject obj=new GameObject();
obj.name="ObjectPoolManager";
instance=obj.AddComponent<ObjectPoolManager>();
}
}
public static void ClearAll(){ //not in used
for(int i=0; i<instance.poolList.Count; i++) instance.poolList[i].Clear();
instance.poolList=new List<Pool>();
}
public static Transform GetOPMTransform(){ return instance.transform; }
public static Transform Spawn(Transform objT, float activeDuration=-1){
return Spawn(objT.gameObject, Vector3.zero, Quaternion.identity, activeDuration).transform;
}
public static Transform Spawn(Transform objT, Vector3 pos, Quaternion rot, float activeDuration=-1){ Init();
return instance._Spawn(objT.gameObject, pos, rot, activeDuration).transform;
}
public static GameObject Spawn(GameObject obj, float activeDuration=-1){
return Spawn(obj, Vector3.zero, Quaternion.identity, activeDuration);
}
public static GameObject Spawn(GameObject obj, Vector3 pos, Quaternion rot, float activeDuration=-1){ Init();
return instance._Spawn(obj, pos, rot, activeDuration);
}
public GameObject _Spawn(GameObject obj, Vector3 pos, Quaternion rot, float activeDuration=-1){
if(obj==null){
Debug.LogWarning("NullReferenceException: obj unspecified");
return null;
}
if(disablePooling){
GameObject objInstance = Instantiate(obj, pos, rot);
if(activeDuration>0) Destroy(objInstance, activeDuration);
return objInstance;
}
int ID=GetPoolID(obj);
if(ID==-1){
if(showUninitiatedPoolWarning)
Debug.LogWarning("ObjectPoolManager: trying to spawn uninitiated object ("+obj+"), creating new pool");
ID=_New(obj);
}
GameObject spawnedObj=poolList[ID].Spawn(pos, rot);
if(activeDuration>0) StartCoroutine(UnspawnRoutine(spawnedObj, activeDuration));
return spawnedObj;
}
IEnumerator UnspawnRoutine(GameObject spawnedObj, float activeDuration){
if(activeDuration>0) yield return new WaitForSeconds(activeDuration);
Unspawn(spawnedObj);
}
public static void Unspawn(Transform objT, float delay){ Init();
instance.StartCoroutine(instance.UnspawnRoutine(objT.gameObject, delay));
}
public static void Unspawn(GameObject obj, float delay){ Init();
instance.StartCoroutine(instance.UnspawnRoutine(obj, delay));
}
public static void Unspawn(Transform objT){ Init(); instance._Unspawn(objT.gameObject); }
public static void Unspawn(GameObject obj){ Init(); instance._Unspawn(obj); }
public void _Unspawn(GameObject obj){
if(disablePooling){
Destroy(obj);
return;
}
for(int i=0; i<poolList.Count; i++){
if(poolList[i].Unspawn(obj)) return;
}
Destroy(obj);
}
public static int New(Transform objT, int count=2){ Init(); return instance._New(objT.gameObject, count); }
public static int New(GameObject obj, int count=2){ Init(); return instance._New(obj, count); }
public int _New(GameObject obj, int count=2){
if(disablePooling) return 0;
int ID=GetPoolID(obj);
if(ID!=-1) poolList[ID].MatchObjectCount(count);
else{
Pool pool=new Pool();
pool.prefab=obj;
pool.MatchObjectCount(count);
poolList.Add(pool);
ID=poolList.Count-1;
}
return ID;
}
int GetPoolID(GameObject obj){
for(int i=0; i<poolList.Count; i++){
if(poolList[i].prefab==obj) return i;
}
return -1;
}
}
[System.Serializable]
public class Pool{
public GameObject prefab;
public List<GameObject> inactiveList=new List<GameObject>();
public List<GameObject> activeList=new List<GameObject>();
public int cap=1000;
public GameObject Spawn(Vector3 pos, Quaternion rot){
GameObject obj=null;
if(inactiveList.Count==0){
obj=(GameObject)MonoBehaviour.Instantiate(prefab, pos, rot);
}
else{
obj=inactiveList[0];
obj.transform.parent=null;
obj.transform.position=pos;
obj.transform.rotation=rot;
obj.SetActive(true);
inactiveList.RemoveAt(0);
}
activeList.Add(obj);
return obj;
}
public bool Unspawn(GameObject obj){
if(obj==null) return false;
if(activeList.Contains(obj)){
obj.SetActive(false);
obj.transform.parent=ObjectPoolManager.GetOPMTransform();
activeList.Remove(obj);
inactiveList.Add(obj);
return true;
}
if(inactiveList.Contains(obj)){
return true;
}
return false;
}
public void MatchObjectCount(int count){
if(count>cap) return;
int currentCount=GetTotalObjectCount();
for(int i=currentCount; i<count; i++){
GameObject obj=(GameObject)MonoBehaviour.Instantiate(prefab);
obj.SetActive(false);
obj.transform.parent=ObjectPoolManager.GetOPMTransform();
inactiveList.Add(obj);
}
}
public int GetTotalObjectCount(){
return inactiveList.Count+activeList.Count;
}
public void Clear(){
for(int i=0; i<inactiveList.Count; i++){
if(inactiveList[i]!=null) MonoBehaviour.Destroy(inactiveList[i]);
}
for(int i=0; i<activeList.Count; i++){
if(activeList[i]!=null) MonoBehaviour.Destroy(inactiveList[i]);
}
}
}