오브젝트 생성 최적화
오브젝트를 여러 개 생성할 때 프레임 드롭이 일어나는 것을 발견하였다.
![]() |
![]() |
30초 정도 게임을 진행시켰을 때 연출을 위해 쌓아둔 바둑돌들이 많이 쌓이며 프레임이 20대까지 떨어진다.
이를 해결하는 방법을 연구해보자.
원인 분석
우선, 씬에 존재하는 오브젝트는 거의 UI이고 성능에 크게 문제 될 것들이 없다.
앞에서 말했듯이 바둑돌이 많이 쌓이는 것이 근본적인 문제인 것 같다.
첫 번째 시도
단순하게 물체가 너무 많은 것 같아 움직이지 않는 바둑돌을 삭제하려는 시도를 했다.
이때, 단순히 삭제하지 않고 바둑돌을 생성하는 객체에서 오브젝트 풀을 이용하여 관리하며 불필요한 생성을 막으려 했다.
바둑돌의 RigidBody의 Sleep을 이용하여 Threshold를 적절히 조절하여 객체를 반환하였다.
void Update()
{
if (isDisposable)
{
if (transform.position.y < -10)
{
OnStop?.Invoke(gameObject);
}
if (_rigidbody && _rigidbody.IsSleeping())
{
OnStop?.Invoke(gameObject);
Debug.Log("Return Stone");
}
}
}
하지만 성능 개선이 되지는 않았다....
우선, 바둑돌이 계속하여 떨어지다 보니 연쇄적으로 충돌이 일어나 Sleep상태로 들어가는 바둑돌이 많지 않았다.
SleepThreshold를 많이 높여도 되지만 갑자기 사라지는 바둑돌이 생기거나 하여 부자연스러울 수 있다고 생각했다.
또한, Sleep을 기준으로 하지 않고 lifeTime이나 개수 제한을 통해 오브젝트 풀링을 해도 되지만 개수를 최대한 유지하며 성능을 개선하고 싶었다.
문제는 Material에 있었다.
바둑돌은 Rendering Mode를 Transparent로 설정하여 바둑돌의 반짝이는 표면을 나타낸다.
Transparent의 경우 Drawing에서 성능을 많이 잡아먹게 된다.

Material을 Opaque로 변경해 봤다.

Drawing에 걸리는 부하는 많이 줄어든 것 같다.
이전에는 드로잉에 걸리는 시간이 5000번째 프레임에도 불구하고 18.73 ms이고 현재는 4.37 ms로 현저히 줄어들었다.
두 번째 시도
하지만, 여전히 프레임이 많이 떨어진다.
Profiler를 살펴보니 물리 연산에서 많은 시간이 소모된다.
너무 많은 바둑돌이 서로 부딪히며 연산이 일어나기 때문이라고 생각하였다.
이를 개선하기 위해 물리 solver의 iteration 수를 조금 낮춰 봤다.
해당 게임은 오목게임이라 정밀한 물리 연산이 필요하지 않다.
그렇기 때문에 물리 연산의 정확도가 조금 떨어져도 괜찮다고 판단하였다.


물리 연산이 38ms에서 5ms로 크게 줄었다.
프레임도 47 정도로 올라왔다.
iteration 수를 1로 낮췄더니 프레임은 더 좋아졌다.

세 번째 시도
어느 정도 성능은 개선된 것 같다.
하지만, 문제는 계속하여 대기한다면 물체가 끊임없이 쌓일 것이고 언젠가는 프레임 드롭이 일어날 것이다.

결국 이를 제어하는 로직이 필요하다.
무한히 생성할 수는 없으니까...
방법은 크게 두 가지인 것 같다.
- 스포너에서 개수 제한하기
- 바둑돌에 LifeTime 주기
개수를 제한하게 되면 운이 좋지 않을 때 이미 모두 생성하여 더 이상 생성하지 않을 수 있다.
따라서, LifeTime을 주도록 해보자.
void Update()
{
if (isDisposable)
{
if (transform.position.y < -10)
{
OnStop?.Invoke(gameObject);
}
if (_rigidbody && _rigidbody.IsSleeping())
{
OnStop?.Invoke(gameObject);
}
if (_lifeTime >= lifeTimeLimit)
{
OnStop?.Invoke(gameObject);
}
}
_lifeTime += Time.deltaTime;
}
LifeTime이상이 되면 객체를 반환하여 새로 생성하도록 만들었다.

확실히 시간제한을 두니 프레임이 떨어지지 않았다.
하지만, 오브젝트의 수를 제한하는 효과와 비슷하니 아쉬움이 있다.
최종 결과

개수를 제한하기는 했지만 프레임이 잘 나온다...
오브젝트 생성 최적화
오브젝트를 여러 개 생성할 때 프레임 드롭이 일어나는 것을 발견하였다.
![]() |
![]() |
30초 정도 게임을 진행시켰을 때 연출을 위해 쌓아둔 바둑돌들이 많이 쌓이며 프레임이 20대까지 떨어진다.
이를 해결하는 방법을 연구해보자.
원인 분석
우선, 씬에 존재하는 오브젝트는 거의 UI이고 성능에 크게 문제 될 것들이 없다.
앞에서 말했듯이 바둑돌이 많이 쌓이는 것이 근본적인 문제인 것 같다.
첫 번째 시도
단순하게 물체가 너무 많은 것 같아 움직이지 않는 바둑돌을 삭제하려는 시도를 했다.
이때, 단순히 삭제하지 않고 바둑돌을 생성하는 객체에서 오브젝트 풀을 이용하여 관리하며 불필요한 생성을 막으려 했다.
바둑돌의 RigidBody의 Sleep을 이용하여 Threshold를 적절히 조절하여 객체를 반환하였다.
void Update()
{
if (isDisposable)
{
if (transform.position.y < -10)
{
OnStop?.Invoke(gameObject);
}
if (_rigidbody && _rigidbody.IsSleeping())
{
OnStop?.Invoke(gameObject);
Debug.Log("Return Stone");
}
}
}
하지만 성능 개선이 되지는 않았다....
우선, 바둑돌이 계속하여 떨어지다 보니 연쇄적으로 충돌이 일어나 Sleep상태로 들어가는 바둑돌이 많지 않았다.
SleepThreshold를 많이 높여도 되지만 갑자기 사라지는 바둑돌이 생기거나 하여 부자연스러울 수 있다고 생각했다.
또한, Sleep을 기준으로 하지 않고 lifeTime이나 개수 제한을 통해 오브젝트 풀링을 해도 되지만 개수를 최대한 유지하며 성능을 개선하고 싶었다.
문제는 Material에 있었다.
바둑돌은 Rendering Mode를 Transparent로 설정하여 바둑돌의 반짝이는 표면을 나타낸다.
Transparent의 경우 Drawing에서 성능을 많이 잡아먹게 된다.

Material을 Opaque로 변경해 봤다.

Drawing에 걸리는 부하는 많이 줄어든 것 같다.
이전에는 드로잉에 걸리는 시간이 5000번째 프레임에도 불구하고 18.73 ms이고 현재는 4.37 ms로 현저히 줄어들었다.
두 번째 시도
하지만, 여전히 프레임이 많이 떨어진다.
Profiler를 살펴보니 물리 연산에서 많은 시간이 소모된다.
너무 많은 바둑돌이 서로 부딪히며 연산이 일어나기 때문이라고 생각하였다.
이를 개선하기 위해 물리 solver의 iteration 수를 조금 낮춰 봤다.
해당 게임은 오목게임이라 정밀한 물리 연산이 필요하지 않다.
그렇기 때문에 물리 연산의 정확도가 조금 떨어져도 괜찮다고 판단하였다.


물리 연산이 38ms에서 5ms로 크게 줄었다.
프레임도 47 정도로 올라왔다.
iteration 수를 1로 낮췄더니 프레임은 더 좋아졌다.

세 번째 시도
어느 정도 성능은 개선된 것 같다.
하지만, 문제는 계속하여 대기한다면 물체가 끊임없이 쌓일 것이고 언젠가는 프레임 드롭이 일어날 것이다.

결국 이를 제어하는 로직이 필요하다.
무한히 생성할 수는 없으니까...
방법은 크게 두 가지인 것 같다.
- 스포너에서 개수 제한하기
- 바둑돌에 LifeTime 주기
개수를 제한하게 되면 운이 좋지 않을 때 이미 모두 생성하여 더 이상 생성하지 않을 수 있다.
따라서, LifeTime을 주도록 해보자.
void Update()
{
if (isDisposable)
{
if (transform.position.y < -10)
{
OnStop?.Invoke(gameObject);
}
if (_rigidbody && _rigidbody.IsSleeping())
{
OnStop?.Invoke(gameObject);
}
if (_lifeTime >= lifeTimeLimit)
{
OnStop?.Invoke(gameObject);
}
}
_lifeTime += Time.deltaTime;
}
LifeTime이상이 되면 객체를 반환하여 새로 생성하도록 만들었다.

확실히 시간제한을 두니 프레임이 떨어지지 않았다.
하지만, 오브젝트의 수를 제한하는 효과와 비슷하니 아쉬움이 있다.
최종 결과

개수를 제한하기는 했지만 프레임이 잘 나온다...