Chapter 9. 오브젝트풀 패턴(ObjectPool Pattern)
카테고리: Design Pattern
인프런에 있는 이재환님의 강의 게임 디자인 패턴 with Unity 를 듣고 정리한 필기입니다. 😀
Chapter 9. ObjectPool Pattern
🔔 개념
오브젝트풀 패턴
👉 '재사용' 가능한 객체들을 모아놓은 객체 풀 클래스를 정의하는 것
- 장점) 메모리를 신경쓰지 않고 마음껏 객체를 생성, 삭제할 수 있다.
- 단점) 객체 아무것도 사용하지 않아도 메모리를 차지하고 있는 상태가 됨.
- 객체 풀 클래스에 들어가는 객체는 현재 자신이 사용중인지 아닌지 알 수 있는 방법을 제공해야 한다.
풀
은 초기화될 때 사용할 객체들을 미리 생성하여 배열에 넣어두고 사용 안함 상태로 초기화 한다.- 새로운 객체가 필요하면
풀
에 요청한다. 풀
은 사용 가능한 객체를 찾아 사용 중으로 초기화 한 뒤 리턴한다.- 객체를 더 이상 사용하지 않는다면 사용 안 함 상태로 되돌린다.
오브젝트풀 패턴을 언제 쓸 것인가?
- 객체를 빈번하게 생성/삭제 해야할 때
- 객체들의 크기가 비슷할 때
- 객체를 힙에 생성하기엔 느리거나 메모리 단편화가 우려될 때
- DB 연결이나 네트워크 연결같이 객체 생성시 비용이 비쌀 경우 미리 생성해두고 재사용할 필요가 있을 때
경량 패턴(Flyweight Pattern)과의 비교
둘 다 재사용 가능한 객체 집합을 관리함
- 경량 패턴
- 같은 인스턴스를 여러 객체에서 공유함으로써 재사용한다.
- 같은 객체를 동시에 여러 문맥에서 사용함으로써 메모리 중복 사용을 피하는게 의도
- 같은 인스턴스를 여러 객체에서 공유함으로써 재사용한다.
- 오브젝트풀 패턴
- 객체를 재사용하긴 하지만 여러 곳에서 동시에 재사용하지는 않는다.
- 이전 사용자가 다 쓴 다음 객체 메모리를 회수해가는 것을 의미할 뿐 공유하는 ㅐ념은 아니다. 객체는 한번에 한곳에서만 사용 됨.
- 객체를 재사용하긴 하지만 여러 곳에서 동시에 재사용하지는 않는다.
📜Enemy.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour {
void OnMouseOver()
{
if (Input.GetMouseButtonDown(0))
{
gameObject.SetActive(false);
}
}
}
- OnMouseOver() 함수
- 마우스 좌클릭 입력이 들어오면
- 이 스크립트가 붙어있는 게임 오브젝트, 즉 자기 자신을 비활성화 시킨다.
📜EnemyManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyManager : MonoBehaviour {
public GameObject enemy; // 프리팹을 여기에 넣어주기
public int poolSize = 10; // Object Pool Size
GameObject[] enemyPool; // 게임 오브젝트 배열
void Start() // 배열에 오브젝트들 생성하여 담기
{
enemyPool = new GameObject[poolSize]; // 배열 생성
for (int i = 0; i < poolSize; ++i)
{
enemyPool[i] = Instantiate(enemy) as GameObject;
enemyPool[i].name = "Enemy_" + i;
enemyPool[i].SetActive(false); // `사용 안함` 상태
}
StartCoroutine("SpawnManager");
}
IEnumerator SpawnManager()
{
while (true)
{
// 2초 마다 배열 안에 있는 객체들이 차례대로 생성될 것
yield return new WaitForSeconds(2.0f);
for (int i = 0; i < poolSize; i++)
{
if (enemyPool[i].activeSelf == true) // ⭐ 이미 setactive(true)인 상태인 오브젝트면 넘어감!!
continue;
float x = Random.Range(-5, 6);
float z = Random.Range(-5, 6);
enemyPool[i].transform.position = new Vector3(x, 0.5f, z); // 랜덤한 위치
enemyPool[i].SetActive(true); // `사용 함` 상태
break;
}
}
}
}
- GameObject[] enemyPool
- 재사용할 객체들을 넣어둘 배열
- poolSize
- 배열의 크기. 즉, 재사용할 객체들의 갯수
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기