Deff_Dev

[Unity/C#] UnityEngine.Pool를 이용한 오브젝트 풀링 본문

Unity(유니티)/유니티 공부

[Unity/C#] UnityEngine.Pool를 이용한 오브젝트 풀링

Deff_a 2024. 5. 23. 17:02

 

유니티에서 오브젝트 풀링을 구현할 때, 리스트, 딕셔너리 등을 이용해 구현을 한다.

 

[Unity/C#] 오브젝트 풀 구현

게임을 만들다보면 프리팹으로 저장된 오브젝트를 생성, 삭제해야할 경우가 생긴다. 예를 들어, 총알을 발사하는 경우를 생각해보자. 이때, 총알 프리팹을 저장한 뒤, Instantiate를 이용하여 총알

deff-dev.tistory.com

 

유니티 자체에서 지원하는 오브젝트 풀 라이브러리에 대해 설명해보려한다.

using UnityEngine.Pool;

 

라이브러리 선언은 위처럼 작성하면 된다.

 

객체 생성

ObjectPool<형식>

초기화

 private ObjectPool<GameObject> pool;
 
     void Awake()
    {
        pool = new ObjectPool<GameObject>(createFunc, actionOnGet, actionOnRelease,
        		actionOnDestroy, collectionCheck, defaultCapacity, maxSize);
    }
  • createFunc: 오브젝트 생성 함수 (Func)
  • actionOnGet: 풀에서 오브젝트를 가져오는 함수 (Action)
  • actionOnRelease: 오브젝트를 비활성화할 때 호출하는 함수 (Action)
  • actionOnDestroy: 오브젝트 파괴 함수 (Action)
  • collectionCheck: 중복 반환 체크 (bool)
  • defaultCapacity: 처음에 미리 생성하는 오브젝트 갯수 (int)
  • maxSize: 저장할 오브젝트의 최대 갯수 (int)

 

ObjectPool를 이용하여, 최소 20개의 오브젝트 수 보장, 부족할 경우 누적 100개까지 추가 생성, 100개가 넘어갈 경우 임시로 생성 후 반환 시 파괴하는 오브젝트 풀을 만들어보겠다.

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

public class ObjectPool4 : MonoBehaviour
{
    private ObjectPool<GameObject> pool;
    private const int maxSize = 100;
    private const int initSize = 20;

    private GameObject prefab;
    void Awake()
    {
        pool = new ObjectPool<GameObject>(CreateObject, ActivatePoolObject, DisablePoolObject , DestroyPoolObject, false, initSize, maxSize);
    }

    private GameObject CreateObject() // 오브젝트 생성
    {
        return Instantiate(prefab);
    }

    private void ActivatePoolObject(GameObject obj) // 오브젝트 활성화
    {
        obj.SetActive(true);
    }

    private void DisablePoolObject(GameObject obj) // 오브젝트 비활성화
    {
        obj.SetActive(false);
    }

    private void DestroyPoolObject(GameObject obj) // 오브젝트 삭제
    {
       Destroy(obj);
    }
    
    public GameObject GetObject()
    {
        GameObject sel = null;

        if (pool.CountActive >= maxSize) // maxSize를 넘는다면 임시 객체 생성 및 반환
        {
            sel = CreateObject();
            sel.tag = "PoolOverObj";
        }
        else 
        {
            sel = pool.Get();
        }

        return sel;
    }

    public void ReleaseObject(GameObject obj)
    {
        if (obj.CompareTag("PoolOverObj"))
        {
            Destroy(obj);
        }
        else
        {
            pool.Release(obj);
        }
    }
}