유니티(Unity)에서 오브젝트 풀(Object Pool) 의 유용성과 사용 예시

반응형

유니티(Unity)에서 오브젝트 풀(Object Pool) 의 유용성과 사용 예시

게임에서 자주 생성하고 파괴되는 오브젝트가 많은 경우 오브젝트 풀(Object Pool)을 사용하면 메모리 할당 및 해제로 인한 성능 저하를 줄일 수 있습니다. 

 

오브젝트 풀(Object Pool) 사용가능 예

총알 발사 시스템 (Bullet Firing System)
총알을 발사할 때마다 새로운 총알 오브젝트를 생성하고 파괴하는 경우

적군 스폰 시스템 (Enemy Spawn System)
적군이 계속해서 스폰되고 사라지는 시스템에서 적 오브젝트의 생성과 파괴가 빈번하게 일어나는 경우

파티클 효과 시스템 (Particle Effects)
폭발, 연기, 불꽃 등 다양한 파티클 효과 짧은 시간 동안 생성되고 빠르게 사라지는 경우
아이템 드롭 시스템 (Item Drop System)
플레이어가 적을 처치할 때마다 아이템이 드롭되는 경우

 

오브젝트 풀 사용하지 않은 경우

총알을 발사할 때마다  Instantiate 함수로 총알 오브젝트를 생성하고 사용 후 Destroy함수로 제거하면 메모리 할당 및 해제 비용이 발생합니다.

public class BulletSpawner : MonoBehaviour
{
    public GameObject bulletPrefab; // 총알 프리팹
    public float fireRate = 0.5f; // 총알 발사 속도
    private float nextFire = 0.0f;

    void Update()
    {
        if (Input.GetButton("Fire1") && Time.time > nextFire)
        {
            nextFire = Time.time + fireRate;
            FireBullet();
        }
    }

    void FireBullet()
    {
        // 총알 생성
        GameObject bullet = Instantiate(bulletPrefab, transform.position, transform.rotation);
        // 총알 파괴 (5초 뒤)
        Destroy(bullet, 5f);
    }
}

오브젝트 풀 사용하는 경우
게임을 시작할때  미리 풀 크기만큼 총알 오브젝트를 생성하고 필요할때 활성화/비활성화하는 방식

public class BulletPool : MonoBehaviour
{
    public GameObject bulletPrefab; // 총알 프리팹
    public int poolSize = 10; // 풀 크기
    public float fireRate = 0.5f; // 총알 발사 속도
    private float nextFire = 0.0f;

    private List<GameObject> bulletPool; // 오브젝트 풀 리스트

    void Start()
    {
        // 오브젝트 풀 초기화
        bulletPool = new List<GameObject>();

        for (int i = 0; i < poolSize; i++)
        {
            GameObject bullet = Instantiate(bulletPrefab);
            bullet.SetActive(false); // 비활성화된 상태로 풀에 저장
            bulletPool.Add(bullet);
        }
    }

    void Update()
    {
        if (Input.GetButton("Fire1") && Time.time > nextFire)
        {
            nextFire = Time.time + fireRate;
            FireBullet();
        }
    }

    void FireBullet()
    {
        
        GameObject bullet = GetPooledBullet();
        if (bullet != null)
        {
            bullet.transform.position = transform.position;
            bullet.transform.rotation = transform.rotation;
            bullet.SetActive(true); // 총알 활성화
        }
    }

    GameObject GetPooledBullet()
    {
        // 비활성화된 총알 반환
        foreach (GameObject bullet in bulletPool)
        {
            if (!bullet.activeInHierarchy)
            {
                return bullet;
            }
        }
        return null; // 풀에 사용 가능한 총알이 없으면 null 반환
    }
}

반응형

댓글

Designed by JB FACTORY