728x90
오브젝트 풀링(Object Pooling)
오브젝트의 생성과 파괴는 꽤 많은 성능을 잡아 먹는다.
생성은 메모리 할당과 리소스 로드, 파괴는 가비지 컬렉션이 동작하기 때문이다.
게임 실행 중 다량의 오브젝트가 생성 및 파괴가 된다면 프레임 드랍 등의 성능 문제가 발생할 것이다.
이를 방지하기 위해 사용하는 기법이 오브젝트 풀링이다.
오브젝트를 필요한 만큼 미리 생성해놓고 필요 할 때 사용하고 사용이 끝나면 다시 풀에 반납하는 방식이다.
다중 오브젝트 풀링(Object Pooling)
하지만 게임을 개발하다보면 오브젝트 풀이 필요한 경우가 생각보다 빈번하다. (투사체, 적, 타일 등)
기본적인 오브젝트 풀 코드에서는 이를 한번에 관리할 수가 없다.
이 문제를 해결하기 위해 여러 코드를 참고하여 다중 오브젝트 풀링(오브젝트 매니저)을 만들었다.
using System;
using System.Collections.Generic;
using UnityEngine;
// 오브젝트 구분을 위한 타입
public enum EPoolObjectType
{
Skill1,
Skill2
}
// 오브젝트 풀
[Serializable]
public class PoolInfo
{
public EPoolObjectType type;
public int initCount;
public GameObject prefab;
public GameObject container;
public Queue<GameObject> poolQueue = new Queue<GameObject>();
}
public class ObjectPoolManager : MonoBehaviour
{
public static ObjectPoolManager Instance;
// 오브젝트 풀 리스트
[SerializeField] private List<PoolInfo> poolInfoList;
private void Awake()
{
Instance = this;
Initialize();
}
// 각 풀마다 정해진 개수의 오브젝트를 생성해주는 초기화 함수
private void Initialize()
{
foreach (PoolInfo poolInfo in poolInfoList)
{
for (int i = 0; i < poolInfo.initCount; i++)
{
poolInfo.poolQueue.Enqueue(CreatNewObject(poolInfo));
}
}
}
// 초기화 및 풀에 오브젝트가 부족할 때 오브젝트를 생성하는 함수
private GameObject CreatNewObject(PoolInfo poolInfo)
{
GameObject newObject = Instantiate(poolInfo.prefab, poolInfo.container.transform);
newObject.gameObject.SetActive(false);
return newObject;
}
// ObjectType(Enum)으로 해당하는 PoolInfo를 반환해주는 함수
private PoolInfo GetPoolByType(EPoolObjectType type)
{
foreach (PoolInfo poolInfo in poolInfoList)
{
if(type == poolInfo.type)
{
return poolInfo;
}
}
return null;
}
// 오브젝트가 필요할 때 호출하는 함수
public static GameObject GetObject(EPoolObjectType type)
{
PoolInfo poolInfo = Instance.GetPoolByType(type);
GameObject objInstance = null;
if (poolInfo.poolQueue.Count > 0)
{
objInstance = poolInfo.poolQueue.Dequeue();
}
else
{
objInstance = Instance.CreatNewObject(poolInfo);
}
objInstance.SetActive(true);
return objInstance;
}
// 오브젝트 사용 후 다시 풀에 반환하는 함수
public static void ReturnObject(GameObject obj, EPoolObjectType type)
{
PoolInfo poolInfo = Instance.GetPoolByType(type);
poolInfo.poolQueue.Enqueue(obj);
obj.SetActive(false);
}
}
위 스크립트를 게임오브젝트(오브젝트 풀 매니저)에 추가면된다.
GameObject instanceObject = ObjectPoolManager.GetObject(poolType);
오브젝트를 생성할 때 위와 같은 형식으로 풀에서 가져오면 된다.
ObjectPoolManager.ReturnObject(gameObject, EPoolObjectType.Skill1);
오브젝트를 파괴할 때는 위와 같은 형식으로 풀에 반환해주면 된다.
- Type : 풀을 구분하기 위한 열거형
- Init Count : 처음 생성할 오브젝트의 수
- Prefab : 복제할 오브젝트(프리팹)
- Container : 오브젝트가 생성될 부모 게임오브젝트(인스펙터상 부모 오브젝트)
잘 작동한다!
참조
'게임 > Unity' 카테고리의 다른 글
[Unity] Rider Debugging (0) | 2023.03.28 |
---|---|
[Unity] \uFFFD Warning (0) | 2023.01.31 |
[Unity] RedRunnder 오픈소스 분석 (0) | 2022.12.14 |
[Unity] 화면 외부에서 오브젝트 생성 (0) | 2022.11.27 |