본문 바로가기
1일 1 구현

[1일 1 구현] PoolManager - 2

by LemongO 2024. 5. 18.

📌PoolManager 구현 코드

 

public class PoolManager : MonoBehaviour
{
    public static PoolManager Instance;

    private Dictionary<string, Pool> _pools = new Dictionary<string, Pool>();

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
            Destroy(gameObject);
    }
    
    public GameObject GetFromPool(GameObject origin)
    {
        if (!_pools.ContainsKey(origin.name))
            CreatePool(origin);        

        return _pools[origin.name].Pop();
    }

    public void ReturnToPool(GameObject go)
    {
        _pools[go.name].Push(go);
    }

    public void CreatePool(GameObject origin)
    {
        Pool pool = new Pool();
        pool.origin = origin;
        pool.Init();

        _pools.Add(origin.name, pool);
    }
}

 

싱글톤은 UIManager와 동일하게 만들어놓은 상태

 

  • GetFromPool - 오브젝트를 꺼내 쓰기 위한 메서드
  • ReturnToPool - 오브젝트를 반환하기 위한 메서드
  • CreatePool - 현재 Dictionary에 해당하는 오브젝트의 Key 가 없을 때 풀을 생성하기 위한 메서드

Dictionary에 풀링할 오브젝트의 이름(name)을 Key로 Pool에 접근을 해 풀링을 하는 로직이다.

PoolManager의 역할은 풀링 할 오브젝트를 받으면 그 오브젝트가 담겨있는 Pool에 접근하는 방식을 가지고 있다.

 

public class Pool
{
    public Queue<GameObject> poolQueue = new Queue<GameObject>();
    public GameObject origin;    

    private readonly int INIT_POOL_SIZE = 100;

    public void Init()
    {
        for (int i = 0; i < INIT_POOL_SIZE; i++)
            CreateObject();
    }

    public void CreateObject()
    {        
        GameObject clone = Object.Instantiate(origin);
        clone.name = origin.name;
        clone.SetActive(false);

        poolQueue.Enqueue(clone);
    }

    public GameObject Pop()
    {
        if (poolQueue.Count == 0)
            CreateObject();

        return poolQueue.Dequeue();
    }

    public void Push(GameObject go)
    {
        go.SetActive(false);
        poolQueue.Enqueue(go);        
    }
}

 

Pool 클래스는 다음과 같은 기능을 한다.

  • 현재 풀에 담겨있는 오브젝트를 관리할 Queue
  • 해당 풀에 들어있는 실제 GameObject 타입 변수 origin
  • CreateObject - 풀에 오브젝트가 더 이상 남아있지 않을 때 새로운 오브젝트를 생성, Queue에 추가
  • Pop - Queue에 담겨있는 오브젝트를 꺼내서 return
  • Push - 매개변수로 GameObject를 받아 현재 Queue에 Enqueue

실제 풀링 시 사용되는 코드는 다음과 같다.

 

꺼내 쓸 때

GameObject clone = PoolManager.Instance.GetFromPool(testPrefab);
clone.SetActive(true);

 

반환 할 때

PoolManager.Instance.ReturnToPool(gameObject);

 

 

모든 것을 코드에서 한다고는 했지만 아직까진 인스펙터에 프리팹을 할당하고 꺼내쓰는 방식이다.

Resources.Load로 해결할 순 있지만 이번 기회에 어드레서블(Addressable)을 사용해서 구현을 해보도록 해야겠다.

'1일 1 구현' 카테고리의 다른 글

[1일 1 구현] Managers.cs  (0) 2024.06.04
[1일 1 구현] PoolManager - 1  (0) 2024.05.16
[1일 1 구현] 코드 정리 및 공통 클래스  (0) 2024.05.15
[1일 1 구현] UI Base  (0) 2024.05.13
[1일 1 구현] UI Manager  (0) 2024.05.13