부트캠프

오브젝트 풀 만들기

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;
    }
}

 

위 코드는 태그와 사이즈라는 부가적인 정보까지 하나의 구조체로 만들고 구조체를 풀링하는 큐와 태그를 묶어 딕셔너리로 구성해 여러 개의 태그와 해당 태그에 해당하는 큐를 가지게끔 구성한 오브젝트 풀이다.

 

●주의사항

오브젝트 풀을 사용할 때 중요한 점은 오브젝트 풀의 갯수를 적절히 유지하는 것이다.

너무 많은 오브젝트를 풀링하고 있다면 메모리의 낭비가 심해지고 너무 적은 수의 오브젝트를 풀링하고 있다면 풀링한 것 이상으로 필요할 때 결국 생성을 해야하므로 성능을 잡아먹게 된다.