오브젝트 풀링

정제로·2023년 10월 11일
0

Unity

목록 보기
17/19

오브젝트풀링

아래와 같이 펑펑 튀기는 효과와 함께 오브젝트를 생성하고 지우는 코드를 작성했다고 가정해보자

성능이 좋은 컴퓨터에서는 충분히 돌아갈만 하지만, 프로젝트 규모가 커지거나, 모바일 기기 같은 경우에서는 렉이 걸리게 될것이다.

유니티에서는 생성과 삭제의 코스트는 크다!

그래서 이런 경우에는 오브젝트 풀링이라는 기술을 사용해주면 좋다!

오브젝트풀링의 기초는 아래와 같다!

오브젝트 풀링이란?

  1. 객체를 원하는 만큼 먼저 만들어놓고, 켜고 끄는 방식으로 오브젝트를 조절하는 방식
  2. 그렇게 되면 객체를 생성하고 소멸시키는 과정을 피할 수 있고, 성능이 향상된다.
  3. 자동적으로 리소스 관리가 쉬워진다. 기본적으로 Pool(수영장)안에 객체들은 꺼져있는 상태로 대기하게 되고, 그로인해 관리가 쉬워진다.

사용법은?

  1. 먼저 객체들이 담길 Pool(수영장)을 만든다.
  2. 수영장에 객체를 원하는 수만큼 담아놓는다.
  3. 생성될때를 가장한, Pool에서 빼고 오브젝트를 켜준다음 반환한다.
  4. 소멸될때를 가장한, 객체를 다시 Pool에 담아주고 오브젝트를 꺼준다.

예제코드

// 이 스크립트는 OBJPOOLMANAGER의 컴포넌트이다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjPoolingManager : MonoBehaviour
{
    public static ObjPoolingManager instance;

    public GameObject cube = null;                              //게임오브젝트
    public Queue<GameObject> pool = new Queue<GameObject>();    //오브젝트 수영장
    public int cubeCount;                                       //게임오브젝트 최대 개수

    void Start()
    {
        instance = this;

        for (int i = 0; i < cubeCount; i++) //수영장에 게임오브젝트를 담아준다. SetActive(false)로
        {
            var instantiatedObj = Instantiate(cube, Vector3.zero, Quaternion.identity);
            pool.Enqueue(instantiatedObj);
            instantiatedObj.SetActive(false);
        }
    }
    public GameObject GetQueue()             // 수영장에 담긴 게임오브젝트를 빼서 SetActive(true)로 해준다음 수영장에서 빼낸다
    {
        var t_obj = pool.Dequeue();
        t_obj.SetActive(true);
        return t_obj;
    }

    public void InsertQueue(GameObject p_obj) // 빼내어진 게임오브젝트를 다시 수영장에 집어넣고 SetActive(false)한다.
    {
        pool.Enqueue(p_obj);
        p_obj.SetActive(false);
    }

}
// 이 스크립트는 OBJPOOLMANAGER의 컴포넌트이다
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CreateCube : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(CreateCoroutine());
    }

    IEnumerator CreateCoroutine()
    {
        while (true)
        {
            yield return null;
            var t_obj = ObjPoolingManager.instance.GetQueue(); //오브젝트풀매니저의 수영장에 등록되어있는 게임오브젝트를 반환받아서 var t_obj에 저장
            t_obj.transform.position = Vector3.zero;           //해당 t_obj의 위치를 0,0,0으로 조정
        }
    }
}
// 이 스크립트는 생성될 오브젝트에 들어가게 될 컴포넌트이다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Cube : MonoBehaviour
{
    Rigidbody rigid = null;

    void OnEnable()
    {
        if (rigid == null)
        {
            rigid = GetComponent<Rigidbody>();
        }

        rigid.velocity = Vector3.zero;
        rigid.AddExplosionForce(1000, transform.position, 0.5f);

        StartCoroutine(DestroyCube());
    }

    IEnumerator DestroyCube() //5초뒤에 오브젝트풀매니저의 수영장에 게임오브젝트를 다시 넣음
    {
        yield return new WaitForSeconds(5f);
        ObjPoolingManager.instance.InsertQueue(gameObject);
    }
}

하이어라키 창을 보면 게임이 시작되면 오브젝트가 입력된 수만큼 미리 생성이 되고, 켜졌다 꺼졌다 하는것을 볼수있다


파티클 흉내내기

이후로 값을 잘 조절하면 아래 사진처럼 파티클과 같이 눈내리는효과 등을 만들수 있다

profile
초보자입니다.. 잘못된 정보, 달게 받겠습니다..

0개의 댓글