using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPoolManager : MonoBehaviour
{
[System.Serializable]
public class Pool
{
public string tag;
public GameObject prefab;
public int size;
}
#region Singleton
public static ObjectPoolManager Instance;
private void Awake()
{
if (Instance != null)
{
//if (Instance != this)
//{
// Destroy(this.gameObject);
//}
}
else
{
Instance = this;
// DontDestroyOnLoad(this);
}
poolDictionary = new Dictionary<string, myPriorityQueue>();
foreach (Pool pool in pools)
{
myPriorityQueue objectPool = new myPriorityQueue();
for (int i = 0; i < pool.size; i++)
{
GameObject obj = Instantiate(pool.prefab, gameObject.transform);
obj.SetActive(false);
obj.transform.SetParent(this.transform);
objectPool.Push(obj);
}
poolDictionary.Add(pool.tag, objectPool);
}
}
#endregion
public List<Pool> pools;
public Dictionary<string, myPriorityQueue> poolDictionary=new Dictionary<string, myPriorityQueue>();
public GameObject SpawnFromPool(string tag, Vector3 position, Quaternion rotation)
{
if (!poolDictionary.ContainsKey(tag))
{
#if UNITY_EDITOR
Debug.LogWarning("Pool withh tag " + tag + "doesn't excist.");
#endif
return null;
}
GameObject objectToSpawn = poolDictionary[tag].top();
poolDictionary[tag].delete();
objectToSpawn.transform.position = position;
objectToSpawn.transform.rotation = rotation;
objectToSpawn.SetActive(true);
IPooledObject pooledObj = objectToSpawn.GetComponent<IPooledObject>();
if (pooledObj != null)
{
pooledObj.OnObjectSpawn();
}
poolDictionary[tag].Push(objectToSpawn);
return objectToSpawn;
}
public void AddPool(string tag,GameObject obj)
{
poolDictionary[tag].Push(obj);
}
public class myPriorityQueue
{
private List<GameObject> q = new List<GameObject>();
public int Count = 0;
private GameObject temp;
public void swap(int a, int b)
{
temp = q[a];
q[a] = q[b];
q[b] = temp;
}
public void Push(GameObject n)
{
// 힙의 맨 끝에 새로운 데이터를 삽입한다.
q.Add(n);
Count++;
int now = q.Count - 1; // 추가한 노드의 위치. 힙의 맨 끝에서 시작.
// 위로 도장 깨기 시작
while (now > 0)
{
int next = (now - 1) / 2; // 부모 노드
if(q[now].activeSelf&&!q[next].activeSelf)//부모가 비활성화고 자식이 활성화면 멈춤.
{
break;
}
// 두 값을 서로 자리 바꿈
swap(now, next);
// 검사 위치로 이동한다.
now = next;
}
}
public GameObject top()
{
return q[0];
}
public GameObject delete()
{
GameObject t = q[0];
q[0] = q[q.Count - 1];
q.RemoveAt(q.Count - 1);
int lastIndex = q.Count - 1;
Count--;
int now = 0;
while (true)
{
int left = 2 * now + 1;
int right = 2 * now + 2;
int next = now;
// 왼쪽 값이 현재값보다 크면, 왼쪽으로 이동
if (left <= lastIndex && q[next].activeSelf&&!q[left].activeSelf)//연산자 바꾸면 반대
{
//부모가 활성화고 자식이 비활성화면 이동
next = left;
}
// 오른쪽 값이 현재값(왼쪽 이동 포함)보다 크면, 오른쪽으로 이동
if (right <= lastIndex && q[next].activeSelf && !q[right].activeSelf)//연산자 반대로
next = right;
// 왼쪽/오른쪽 모두 현재값보다 작으면 종료
if (next == now)
break;
// 두 값 서로 자리 바꿈
swap(next, now);
// 검사 위치로 이동한다.
now = next;
}
return t;
}
}
}
좋은 방법이 있다면 알려주쇼!!
해당 댓글은 삭제되었습니다.
총을 쏘면 총알이 날아가서 맞고 처리 후에 비활성화 되는 데 그걸 일일이 다하고 꺼낼 때 false인 오브젝트를 탐색해서 꺼내는 걸 우선순위 큐 삽입 하고 꺼낼 때 이미 다 해놓을려고 쓴거긴한데... 아니면 다른 방법으로 풀을 2개 만들어서 비활성화 쪽에 쓰고 남은걸 옮기고 거기서 꺼내면 저런거 안써도되는데 그렇게 만들긴 귀찮고해서 택한 방법 ㄷㄷ;;ㅋㅋ
왠만하면 내장을 쓰는게 좋지 않을까.. 나름 거기 훌륭한 사람들이 만들었을테넫
ㅇㅎ, 님도 저거 내장 쓰심? 내일 함 쭉 살펴보고 괜찮으면 다시 갈아야겠삼.
아니 나는 언리얼 함.. 쏘리
귀찮아서 그냥 내장 풀 쓰는데.. 저렇게까지 해서 의미있을정도로 최적화가 잘 되면 좋겠는데 이렇게 질문글 쓸 정도면 애매하다는거거나 혹은 아직 그렇게 최적화가 필요없는 부분에 시간을 낭비하고 있다는 뜻 아닐까