본문 바로가기
  • 피곤한 일상에 초록물약 한잔
개발일지(Unity)

[Unity/C#] 오브젝트풀(Object Pool)

by 0r4c13 2022. 2. 26.
반응형

git => https://github.com/0r4c1E/ObjectPoolManager

 

GitHub - 0r4c1E/ObjectPoolManager

Contribute to 0r4c1E/ObjectPoolManager development by creating an account on GitHub.

github.com

(깃에 올라간 버전은 상시 업데이트 합니다)

 

 

 

항상 사용하고있던 오브젝트 풀을 조금 개량해보았다.

 

기존에 사용하던 오브젝트 풀은 Dictionary가 아닌 List를 이용해서 Inspector에 넣어둔 List순번을 id값으로 이용하여 당겨왔지만, 얼마전 코드리뷰를 진행하며 차후 확인할때 오히려 헷갈릴 수 있다는 조언을 들어 업데이트 하게 되었다.

 

작명 규칙을 따로 정해서 적응하게 되면 추후 프로젝트에서 헷갈일일 없이, 일일히 inspector를 보지 않아도 사용할수 있을것으로 보인다.

 

메서드를 전부 정적메서드로 작성하였는데, 이게 좋을지 아닐지는 아직 모르겠지만, 이후 공부하며 깨닿는 바가 있다면 고칠거라고 생각이 든다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]

///<summary>
/// 풀링할 프리팹 오브젝트 입력용
///</summary>
public class PoolItem
{
    public string key;
    public GameObject item;
}
///<summary>
/// 0r4c1E's ObjectPoolManager ===== ver. 2.0
///</summary>
public class PoolManager : MonoBehaviour
{
    public static PoolManager inst;
    [Header("Set Pooling Object & Key")]
    ///<summary>
    /// 풀링할 오브젝트와 키값을 입력
    ///</summary>
    public List<PoolItem> objects;

    ///<summary>
    /// 풀링한 오브젝트들을 보관
    ///</summary>
    private Dictionary<string, Queue<GameObject>> items;
    Queue<GameObject> _buff;
    GameObject _obj;

    private void Awake()
    {
        inst = this;
    }
    ///<summary>
    /// 모든 오브젝트를 입력한 숫자만큼 풀링하는 메서드
    ///</summary>
    ///<param name="cnt"> 각 항목당 풀링할 갯수 </param>
    public static void ObjectPool(int cnt)
    {
        for (int i = 0; i < inst.objects.Count; i++)
        {
            inst._buff = new Queue<GameObject>();
            for (int j = 0; j < cnt; j++)
            {
                inst._buff.Enqueue(CreateObject(i));
            }
            inst.items.Add(inst.objects[i].key, inst._buff);
        }
    }
    ///<summary>
    /// 특정 오브젝트를 만들어주는 메서드
    ///</summary>
    ///<param name="id"> 'objects'에서의 리스트 번호 </param>
    public static GameObject CreateObject(int id)
    {
        inst._obj = Instantiate(inst.objects[id].item, Vector3.zero, Quaternion.identity);
        inst._obj.SetActive(false);
        return inst._obj;
    }
    ///<summary>
    /// 입력한 오브젝트를 Return 시켜주는 메서드
    ///</summary>
    ///<param name="key"> 'items'에서의 딕셔너리 키값 </param>
    public static GameObject GetPoolItem(string key)
    {
        if (inst.items[key].Count > 0)
        {
            inst._obj = inst.items[key].Dequeue();
        }
        else
        {
            inst._obj = CreateObject(ReturnListCount(key));
        }
        return inst._obj;
    }
    ///<summary>
    /// 입력한 'key'값에 맞는 'objects'상의 리스트 번호를 리턴
    ///</summary>
    ///<param name="key"> 'items'에서의 딕셔너리 키값 </param>
    public static int ReturnListCount(string key)
    {
        for (int i = 0; i < inst.objects.Count; i++)
        {
            if (inst.objects[i].key == key) return i;
        }
        return 0;
    }
    ///<summary>
    /// 오브젝트를 'items'의 큐로 되돌리는 메서드
    ///</summary>
    ///<param name="key"> 'items'에서의 딕셔너리 키값 </param>
    ///<param name="obj"> 되돌릴 게임오브젝트 </param>
    public static void ReturnPoolObject(string key, GameObject obj)
    {
        inst.items[key].Enqueue(obj);
    }
}

 

 

반응형

댓글