오브젝트 풀링이란, 최적화 기법으로 하나의 풀(컬렉션)에 여러개의 오브젝트들을 저장하여 관리하는 것이다. 유니티에서 게임오브젝트를 파괴하고 생성하는 것은 많은 연산이 필요하므로 게임오브젝트를 활성화/비활성화 하여 연산을 줄일 수 있다. 이 때, 비활성화된 게임오브젝트를 풀에 저장하거나 풀에서 꺼내어 활성화하는 것을 오브젝트 풀링이라고 한다. 그러므로, 게임 오브젝트가 많아질 수록 오브젝트 풀링을 활용하여 효율적으로 메모리를 사용할 수 있다.

 

유니티에서의 오브젝트 풀링 구현

 

 

CubeGenerator

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

public class CubeGenerator : MonoBehaviour
{
    public GameObject go;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            ObjectPoolManager.Instance.pool.Pop().transform.position = this.go.transform.position;
        }
    }
}

 - 오브젝트 풀링에 사용될 게임오브젝트를 생성할 스크립트

 

 

OjbectPoolManager

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

public class ObjectPoolManager : MonoBehaviour
{
    private static ObjectPoolManager instance;
    public static ObjectPoolManager Instance
    {
        get 
        { 
            return instance; 
        }
    }
    public ObjectPool pool;
    

    private void Awake()
    {
        if (instance) //싱글턴 인스턴스가 1개로 유지되도록 조건 설정
        {
            Destroy(this.gameObject);
            return;
        }

        instance = this;
    }
}

 - 싱글턴 패턴을 활용하여 오브젝트 풀링을 구현한다.

 

 

ObjectPool

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

public class ObjectPool : MonoBehaviour
{
    public Poolable poolObj; 
    public int maxCnt;
    private Stack<Poolable> poolStack = new Stack<Poolable>();

    private void Start()
    {
        this.Allocate();
    }

    public void Allocate()
    {
        for(int i = 0; i < maxCnt; i++)
        {
            Poolable allocateObj = Instantiate(this.poolObj, this.gameObject.transform);
            allocateObj.Create(this);
            this.poolStack.Push(allocateObj);
        }
    }

    public GameObject Pop()
    {
        Poolable obj = this.poolStack.Pop();
        obj.gameObject.SetActive(true);
        return obj.gameObject;
    }

    public void Push(Poolable poolableObj)
    {
        poolableObj.gameObject.SetActive(false);
        this.poolStack.Push(poolableObj);
    }
}

 - 멤버 변수 maxCnt를 통해 오브젝트 풀링의 컬렉션이 소유할 수 있는 최대 인스턴스 갯수를 설정

 - Allocate 메서드를 Start 메서드에서 실행하여 maxCnt 갯수만큼 인스턴스 생성 후 스택배열에 저장

 - CubeGenerator 클래스에서 마우스 우클릭을 인식하여 Pop 메서드 실행 -> 스택배열에 저장된 인스턴스가 활성상태로 전환 

 

 

Poolable

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

public class Poolable : MonoBehaviour
{
    protected ObjectPool pool;

    public virtual void Create(ObjectPool pool)
    {
        this.pool = pool;
        this.gameObject.SetActive(false);
    }

    public virtual void Push()
    {
        pool.Push(this);
    }
}

 - 해당 클래스를 Cube에 상속하여 오브젝트 풀링 될 게임 오브젝트를 제어한다

 - Create 메서드를 통해 게임오브젝트가 풀링될 때 비활성화 상태로 만든다.

 - Push 메서드를 통해 Cube가 특정 상황에서 다시 스택배열로 저장되도록 기능을 만들어 놓는다.

 

 

Cube

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

public class Cube : Poolable
{
    Rigidbody rBody;
    Vector3 dir;

    private void Awake()
    {
        this.rBody = GetComponent<Rigidbody>();
        this.dir = transform.right;
    }

    private void OnEnable()
    {
        this.rBody.AddForce(this.dir * 100f);
    }

    private void OnBecameInvisible()
    {
        this.Push();
    }
}

 - 카메라에서 사라질 때 상속 받은 Poolable 클래스의 Push 메서드를 실행하여 스택 배열에 저장한다.

 

 

 

오브젝트 풀링 구현

 

 

참조

https://a6ly.dev/93

+ Recent posts