부트캠프
오브젝트 풀 만들기
noyyo
2023. 9. 18. 21:07
● 오브젝트 풀이란 ?
게임 내에서 자주 생성되고 삭제되어야 하는 객체들이 있다.
대표적으로 총알과 같은 투사체가 그러한 객체들이다.
하지만 유니티에서 게임 오브젝트를 만들고 지우는데는 꽤나 큰 비용이 발생한다. 그런 비용을 줄이기 위해 쓰는 것이 오브젝트 풀이다.
미리 오브젝트를 생성해놓고 필요할 때 꺼내서 쓴 다음 파괴되어야 하는 상황에서 파괴하는 것이 아니라 오브젝트 풀로 다시 가져온 뒤 비활성화한 상태로 보관해놓고 있다가 다음 필요할 때에 다시 꺼내쓰는 방식이다.
● 구현 방법
구현하는 방법이 복잡한 것은 아니다. 게임 오브젝트를 저장하고 있을 큐 하나, 그리고 큐에서 게임 오브젝트를 꺼내거나 넣을 기능정도만 있어도 충분하다.
필요하다면 여기에 태그라던가 부가적인 정보를 넣어서 딕셔너리 등으로 구성할 수 있다.
큐를 사용하는 이유는 지속적으로 게임 오브젝트를 빌려주고 돌려받기 때문에 같은 객체를 여러 번 빌려주지 않도록 하기 위함의 목적이다.
● 구현 코드
public class ObjectPool : MonoBehaviour
{
[System.Serializable]
public struct Pool
{
public string tag;
public GameObject prefab;
public int size;
}
public List<Pool> pools;
public Dictionary<string, Queue<GameObject>> poolDictionary;
private void Awake()
{
poolDictionary = new Dictionary<string, Queue<GameObject>>();
foreach (var pool in pools)
{
Queue<GameObject> objectPool = new Queue<GameObject> ();
for (int i = 0; i < pool.size; i++)
{
GameObject obj = Instantiate(pool.prefab);
obj.SetActive(false);
objectPool.Enqueue (obj);
}
poolDictionary.Add (pool.tag, objectPool);
}
}
public GameObject SpawnFromPool(string tag)
{
if (!poolDictionary.ContainsKey(tag))
return null;
GameObject obj = poolDictionary[tag].Dequeue();
return obj;
}
}
위 코드는 태그와 사이즈라는 부가적인 정보까지 하나의 구조체로 만들고 구조체를 풀링하는 큐와 태그를 묶어 딕셔너리로 구성해 여러 개의 태그와 해당 태그에 해당하는 큐를 가지게끔 구성한 오브젝트 풀이다.
●주의사항
오브젝트 풀을 사용할 때 중요한 점은 오브젝트 풀의 갯수를 적절히 유지하는 것이다.
너무 많은 오브젝트를 풀링하고 있다면 메모리의 낭비가 심해지고 너무 적은 수의 오브젝트를 풀링하고 있다면 풀링한 것 이상으로 필요할 때 결국 생성을 해야하므로 성능을 잡아먹게 된다.