오브젝트 풀링이란?
오브젝트 풀링이란
Pool 은 웅덩이를 뜻하는 영단어로 쉽게 말하면 웅덩이(메모리) 를 미리 할당해 두어 해당 메모리에서 객체를 활성화하여 사용하는 방식으로 일반적으로 객체를 생성 - 파괴하며 메모리에 할당 해제를 계속 하는 것에 비해 CPU 부담을 덜수 있다.
하지만 메모리를 미리 점유하기 때문에 메모리를 희생하고 CPU의 순간순간의 부담을 덜어내는 것이기도 하다.
때문에 메모리 관리 차원에서 또 다른 문제가 있을수 있다.
우선 이전까지 해왔던 식으로 객체를 생성후 메모리에 할당해주고 다시 객체를 지움으로 메모리 할당을 해제하는 코드를 짜보았다. (0.1초마다 객체를 랜덤한 위치에 생성하고 이후 1000개가 만들어지면 다시 0.001초마다 객체를 지우는 코드)
using UnityEngine;
public class EenemyGenerator : MonoBehaviour
{
public GameObject Enemy;
float time;
int sum;
bool isFinished;
void Update()
{
if (!isFinished)
{
time += Time.deltaTime;
if (time > 0.001f)
{
float randomX = Random.Range(-9f, 9f);
float randomY = Random.Range(-4.2f, 4.2f);
Enemy.transform.position = new Vector3(randomX, randomY, 0);
Instantiate(Enemy);
time = 0f;
sum++;
}
}
if (sum == 1000)
{
isFinished = true;
time += Time.deltaTime;
if (time > 0.001f)
{
Enemy = GameObject.Find("Enenmyprefab(Clone)");
Destroy(Enemy);
time = 0f;
}
}
}
}
그럼 이번엔 반대로 미리 메모리에 할당을 해주고 이후 하나하나씩 생성해보는 방식을 짜보았다.(생성 루틴은 위와 동일하다)
using System.Collections.Generic;
using UnityEngine;
public class EenemyGenerator2 : MonoBehaviour
{
public GameObject Enemy;
public List<GameObject> Enemies;
float time;
int index;
bool isDone;
void Start()
{
for (int i = 0; i < 1000; i++)
{
GameObject newBorn = Instantiate(Enemy);
newBorn.SetActive(false);
Enemies.Add(newBorn);
}
}
void Update()
{
if (!isDone)
{
time += Time.deltaTime;
if (index == 1000) isDone = true;
else if (time > 0.001f)
{
time = 0f;
Enemies[index].transform.position = new Vector2(Random.Range(-9f, 9f), Random.Range(-4.2f, 4.2f));
Enemies[index++].SetActive(true);
}
}
if (isDone)
{
time += Time.deltaTime;
if (time > 0.01f && index > 0)
{
Enemies[--index].SetActive(false);
time = 0f;
}
}
}
}
이런식으로 했을때 게임을 시작했을때 시작 버튼을 누르자 마자 하이어라키 창에 1000개의 오브젝트가 눈 깜짝할 사이에 셍상 되었고, 생성되어있는 오브젝트를 빠르게활성화 하며 기존 보다 좀더 부드럽게 생성되는 걸 느낄수 있긴 했다.
(사실 2d오브젝트를 어떤 방식으로 아무리 빠르게 생성한다 하여도 성능에서 큰 차이는 느끼기 어렵긴 하지만)
지금은 단순한 2D오브젝트를 사용하였지만 만약 컴포넌트가 많이 부착된 3D 오브젝트를 많이 빠르게 생성해야 하는 상황이라면 충분히 극초반 객체 로딩을 제외하면 (메모리를 미리 할당해 두기 때문에 게임 뷰 시작시 아주 약간의 프레임 드랍이 아주 짧게 있긴 했다.) 최적화에 큰 도움을 줄수 있을것이라 생각되었다.
PS. 추가로 코루틴을 좀 사용해 보았지만 아직 프레임을 스킵하며 제어권을 유니티로 넘기는 부분을 예상하는게 조금 미숙하여 좀더 연습을 해봐야겠다. (슬슬 감이 잡히긴 한다...)
'유니티 엔진 클라이언트 > 수업 과제' 카테고리의 다른 글
[유니티] Setting 창 제작 (클립보드 복사 플러그인) (0) | 2023.02.19 |
---|---|
[유니티] 상점 탭메뉴 스크롤 연동 (0) | 2023.02.19 |
[유니티] 종스크롤 2D 스페이스 슈터 ver1.1 (0) | 2023.02.11 |
[유니티] 클로저 - 반복문 안에서의 람다 사용시 주의사항 (2) | 2023.02.06 |
[유니티] 코루틴 & 스레드 (0) | 2023.02.01 |