Unity
[Unity] 디자인 패턴 - 오브젝트 풀링
habbn
2025. 2. 20. 00:44
728x90
오브젝트 풀링
빈번하게 사용하는 객체 및 오브젝트에 대하여 매번 새로 생성하고 삭제하는 것이 아닌 미리 생성한 오브젝트를 재사용하는 기법이다.
유니티에서 오브젝트를 생성하거나 삭제할 때 Instantiate()와 Destroy() 함수를 사용하는데, 새로 할당하고 삭제하는 과정에서 많은 시간과 메모리를 잡아먹는다. (가비지 컬렉터가 자주 발생 , 메모리 단편화 발생)
예제 코드
(1) Bullet 스크립트
using UnityEngine;
public class Bullet : MonoBehaviour
{
private float speed = 10f;
public void Init(Vector3 direction)
{
GetComponent<Rigidbody>().velocity = direction * speed;
Invoke(nameof(ReturnToPool), 2f); // 2초 후 자동 반환
}
private void ReturnToPool()
{
gameObject.SetActive(false);
}
}
(2) ObjectPool 스크립트
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool : MonoBehaviour
{
public GameObject prefab; // 미리 생성할 프리팹
public int poolSize = 10; // 초기 생성 개수
private Queue<GameObject> pool = new Queue<GameObject>();
private void Start()
{
for (int i = 0; i < poolSize; i++)
{
GameObject obj = Instantiate(prefab);
obj.SetActive(false);
pool.Enqueue(obj);
}
}
public GameObject GetObject()
{
if (pool.Count > 0)
{
GameObject obj = pool.Dequeue();
obj.SetActive(true);
return obj;
}
else
{
GameObject newObj = Instantiate(prefab);
return newObj;
}
}
public void ReturnObject(GameObject obj)
{
obj.SetActive(false);
pool.Enqueue(obj);
}
}
(3) 총알을 발사하는 GunController 스크립트
using UnityEngine;
public class GunController : MonoBehaviour
{
public ObjectPool bulletPool;
public Transform firePoint;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)) // 스페이스바를 누르면 총알 발사
{
Shoot();
}
}
void Shoot()
{
GameObject bullet = bulletPool.GetObject();
bullet.transform.position = firePoint.position;
bullet.transform.rotation = firePoint.rotation;
bullet.GetComponent<Bullet>().Init(firePoint.forward);
}
}
최적화 팁
1. 오브젝트가 너무 많이 생성되지 않도록 풀 크기를 적절히 조절
2. ReturnToPool()을 호출할 때 CancelInvoke()를 사용하여 중복 실행 방지
3. OnDisable()을 활용하면 풀로 반환되는 시점을 자동으로 처리 가능
728x90