[디자인 패턴] Object Pooling (오브젝트 풀링)

⭐ 오브젝트 풀링

수 많은 오브젝트들이 생성, 파괴될 경우 많은 비용을 요구하기 때문에 생성과 삭제 대신 활성화, 비활성화를 통해 관리하는 패턴입니다.

 

 

게임을 개발하다보면 엄청난 수의 오브젝트들을 생성하고 파괴해야하는 경우가 있습니다.

예를 들어 수 많은 총알 오브젝트들을 발사하거나, 뱀파이어 서바이벌 장르의 게임에선 엄청난 양의 몬스터들이 끊임없이 몰려와야 할 것 입니다.

이렇게 수 많은 오브젝트들의 생성과 파괴가 반복되면 계속해서 객체를 할당 / 해제하기 때문에 성능에 부하가 오고 프레임 드랍을 유발하게 됩니다.

 

이처럼 오브젝트의 생성과 파괴로 인해 성능적인 디메리트를 극복하기 위해 오브젝트 풀링을 사용합니다.

 

 

 

 

 

⭐ 오브젝트 풀링을 사용하는 이유?

오브젝트를 생성, 파괴하는 과정에서 생기는 성능적인 문제를 극복하기 위해 객체를 미리 생성해두고 사용하는 기법

 

성능 최적화

    ○ 미리 생성된 오브젝트를 활성화 / 비활성화 하기 때문에 GC 없음

    ○ 생성해둔 객체가 모자란 경우에만 새로 생성

    ○ 제네릭을 통해 구현하면 다양한 타입에서 쉽게 사용 가능

 

● 사실 자주 쓰이는 오브젝트에서 성능 하나만으로도 쓰이는 이유가 충분!!

    ○ OnEnable(), OnDisable() 등을 통해 데이터 초기화 등도 간단하게 구현

 

 

 

 

 

 

⭐ 제네릭을 이용한 오브젝트 풀링 구현하기

제네릭을 통해 다양한 타입의 오브젝트 풀링을 간단하게 구현할 수 있습니다.

 

 

더보기
using System.Collections.Generic;
using UnityEngine;

public class ObjectPoolling<T> : MonoBehaviour where T : MonoBehaviour
{
    protected Dictionary<string, Queue<T>> objectDatas = new Dictionary<string, Queue<T>>();

    public T Get(T type, Transform pos)
    {
        T data;
        string name = type.name;

        if(!objectDatas.ContainsKey(name))
        {
            objectDatas.Add(name, new Queue<T>());
        }

        Queue<T> queue = objectDatas[name];

        if(queue.Count <= 0)
        {
            data = Instantiate(type, pos);
            data.name = name;
        }
        else
        {
            data = queue.Dequeue();
            data.gameObject.SetActive(true);

        }

        data.transform.position = pos.position;
        data.transform.SetParent(transform);
        return data;
    }

    public void Take(T type)
    {
        string name = type.name;

        if(!objectDatas.ContainsKey(name))
        {
            objectDatas.Add(name, new Queue<T>());
        }

        type.gameObject.SetActive(false);
        objectDatas[name].Enqueue(type);
    }
}