214 lines
5.5 KiB
C#
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]);
|
|
}
|
|
}
|
|
}
|
|
|