[UNITY]/TIL: UNITY

[Unity] ObjectPool(오브젝트풀) 끝장내기

네,가능합니다 2024. 10. 24. 21:47

강의를 듣는다고 바빠서 오늘은 TIL을 뭘 쓸지 정하지못했다..

강의를 들으면서 배운 내용은 강의를 다 들은 후 한번에 정리해서 이해하는 시간을 가져보려고 하기 떄문이다.

오늘따라 집중이 잘 안돼서 강의를 많이 못들어서 TIL을 작성하고 또 강의를 들을려고 한다.

 

그래서 ! 오늘의 TIL은 오브젝트풀 끝장내기다 !!

 

챌린지반의 꾸준실습 문제로 나온 오브젝트풀 구현사항 3가지를 모두 구현해보려고 한다.

(1개만 하게됨..)

 

방법은 유니티에서 제공하는 API를 사용해서 구현을 할 것이다. 

이해가 안되는 부분이 있다면 오브젝트풀 이 링크에 들어가서 오브젝트풀에관해 공부하고 오는것을 추천한다.

 

구현사항은 아래와 같다.

 

[구현사항 1]

최소 50개의 오브젝트 수 보장, 부족할 경우 누적 300개까지 추가 생성, 300개가 넘어갈 경우 임시로 생성 후 반환 시 파괴

 

300개가 넘어가면 AddComponent를 통해 컴포넌트를 추가하고 그 컴포넌트에 있는 정보를 활용하여 임시오브젝트인지 확인한다.

using UnityEngine;
using UnityEngine.Pool;

public class ObjectPoolManager : MonoBehaviour
{
    [SerializeField] private GameObject prefab;
    private IObjectPool<GameObject> pool;
    private int maxSize = 300;

    private void Awake()
    {
        pool = new ObjectPool<GameObject>(
            CreatePooledItem,
            OnTakeFromPool,
            OnReturnedToPool,
            OnDestroyPoolObject,
            defaultCapacity: 50,
            maxSize: maxSize
        );
    }

    private GameObject CreatePooledItem()
    {
        return Instantiate(prefab);
    }

    private void OnTakeFromPool(GameObject obj)
    {
        obj.SetActive(true);
    }

    private void OnReturnedToPool(GameObject obj)
    {
        TempObjectData tempData = obj.GetComponent<TempObjectData>();
        
        if (tempData != null && tempData.isTempObject)
        {
            Destroy(obj);
        }
        else
        {
            obj.SetActive(false);
        }
    }

    private void OnDestroyPoolObject(GameObject obj)
    {
        Destroy(obj);
    }

    public GameObject GetFromPool()
    {	// CountActive > 활성화된 오브젝트 수 반환
    	// CountInactive > 비활성화된 오브젝트 수 반환
        if (pool.CountActive + pool.CountInactive < maxSize)
        {
            return pool.Get();
        }
        else
        {
            GameObject tempObj = Instantiate(prefab);
            TempObjectData tempData = tempObj.AddComponent<TempObjectData>(); // 임시 오브젝트 정보 추가
            tempData.isTempObject = true;
            return tempObj;
        }
    }

    public void ReturnToPool(GameObject obj)
    {
        pool.Release(obj);
    }
}

다른 구현사항도 있지만,, 이 첫번째 구현사항에서 다 응용할 수 있는거라 여기까지만 해보도록 하겠다..

 

처음에는 String값으로 비교했다가 성능적으로 별로인것같아서 바꿨는데 이것도 결국 겟 컴포넌트를 계속 호출하는 방식이다.

 

가장 좋은건 뭘까 고민하게 되는 하루이다..