본문 바로가기
다이어리/내일배움 개발일지

게임개발캠프 - 최종프로젝트 5일차

by E.Clone 2024. 3. 13.

과정명 : 내일배움캠프 Unity 게임개발 3기

전체진행도 : 53일차

부분진행도 : ChapterF - 5일차

작성일자 : 2024.03.12(화)

개발일지 목록 : 클릭


1. 진행중인 과정에 대해

3D 탄막 게임에서 탄막 관리 시스템을 맡아 구현중이다.

2. 오늘 학습에 대해

연쇄 패턴 테스트 중 프레임 저하 이슈

문제의 발생

누가봐도 최적화 문제 + 왠지 씬에 남아있는 투명한 탄막 + 뭔가 시간이 지날수록 점점 무거워지는 게 무엇인가가 메모리에 누적되어가는 것 같은 문제

0.3 FPS (3035.8ms)를 보이며 도저히 게임을 진행할 수 없는 상태로 보인다.
(20만 배치수가 무척 심각한 상태라는 것은 이슈를 해결하고 나서야 알았다)

영상으로 보면 아래와 같다.

이후 탄막의 렌더러를 없애봐도 비슷한 타이밍에 fps가 나락가는 걸 보면, 정말 단순하게 연산쪽이 무거워서 그런 것으로 보인다(코드가 지저분해서 그럴 만 하다고 생각했다)

버그 픽스를 위해

  • 오브젝트 풀에서 초기화 또는 반환 도중 에러가 난 아이들

원점에 돌아갔지만, 움직이지 않고 Update문을 반복하며 오류를 뿜는다.

  • 초기화 오류인가, 반환 오류인가?

수동으로 반환 메서드를 실행하면 잘 되며, 여러가지 초기화 해 주어야 할 값이 모두 null인 것으로 보아, 초기화가 제대로 이루어지지 않은 것으로 보인다.
즉 DanmakuGenerator에서 미스가 있다.

var danmakuGo = DanmakuPoolManager.instance.GetGo(settings.danmakuPrefab.name);
try
{
if (danmakuGo != null)
{
Vector3 initPosition = masterTransform.position; // 마스터의 위치를 기본값으로

// ... 기타 로직 및 탄막 파라미터들 초기화
}
}
catch
{
Pool.Release(danmakuGo);
}

 

아무래도 로직 도중 masterObject가 소실되어 Pool에서의 탄막 생성 후 이후 로직이 모두 무산되고 danmakuController.Initialize도 실행되지 않은 것으로 보인다.
해당 로직을 try문으로 감싸, 초기화가 제대로 이루어지지 않을 경우 바로 Pool에 반환을 할 수 있도록 해야겠다.

var danmakuGo = DanmakuPoolManager.instance.GetGo(settings.danmakuPrefab.name);
try
{
    if (danmakuGo != null)
    {
        Vector3 initPosition = masterTransform.position; // 마스터의 위치를 기본값으로

        // ... 기타 로직 및 탄막 파라미터들 초기화
    }
}
catch
{
    Pool.Release(danmakuGo);
}

해결되지 않았다.
아직 활성화 직전인 오브젝트를 반환 할 수 없는 게 이유인 것으로 보인다.
새로운 탄막 오브젝트를 Pool에서 꺼내오기 전에 masterObject의 상태를 체크하여 코루틴을 종료 할 수 있도록 해 보았다.

// masterObject의 상태 확인
if (masterObject == null || !masterObject.activeInHierarchy)
{
    yield break; // masterObject가 비활성화되거나 파괴되면 코루틴 중단
}
var danmakuGo = DanmakuPoolManager.instance.GetGo(settings.danmakuPrefab.name);

해결 된 듯 보여 탄막 오브젝트를 1.6^4 = 6.6배정도 증량하여 더 부하를 줘 보았다.

FPS가 1.0 이하로 떨어지고 탄막의 반환이 살짝 늦을지언정 더 이상 Pool 버그는 일어나지 않았다.

참고로 위 영상에서 최대 탄막수는 4096개였다. Pool의 크기는 100였기 때문에, 사실상 Instantiate와 Destroy가 커버를 친 셈.

번외로 Pool의 크기를 4100으로 하여 FPS를 확인 해 보자. 버그를 찾으며 프로파일러를 확인하면서, Destory 등이 CPU성능이 90프로 이상인 시점이 있었던 것도 생각하면 왠지 FPS 저하가 플레이에 지장이 없을 정도가 될 것이라고도 생각된다.

워메… 아니었다. 프로파일러를 켜고 다시 확인 해 보자.

일단 랜더러쪽은 전혀 문제가 되지 않았고, 정말 그냥 Pool 반환을 위한 Deactive 량이 너무 많은 것이 원인이었다.(1.6초에 4000회) 그런데 이 반환 처리가 생성파괴와 성능차이가 크게 나지 않는다는 건 생각보다 쇼크.

생명주기 시간을 좀 늘려 반환이 이루어지지 않는 시점에도 FPS가 많이 떨어지는지 확인 해 보아야겠다. 실제 게임에서는 반환이 이렇게 짧은 시간에 대량으로 몰려있지는 않을 것으로 예상되기 때문에.

생성이 갑작스럽게 한꺼번에 이루어져 7.7 FPS를 가지긴 했지만, 이후 약 5000개의 탄막 오브젝트가 이동하는 데에는 11.5 FPS부터 시작하여 약 20 FPS까지 올라간다.

생각 해 보니 하이에라키 등 게임 씬 이외의 요소가 성능저하의 문제가 될 가능성이 있어, Play Maximized 모드에서 추가로 확인을 해 보았다.

생성순간이 13 FPS, 이후 18 FPS부터 시작하여 카메라에서 탄막이 사라지면서(낮아지는 Batches 수) 30 FPS 이상까지 회복한다. Play Maximized 모드에서 대략 1.5배정도의 성능을 보였다.

보스몬스터가 탄막을 무척 남발하도록 하고 싶은데, 이런 상태라면 좀 어려울 것으로 생각된다. 최적화가 필요한 부분이다.

다만, 현재 최우선순위는 패턴의 다양화이고, 이후 탄막의 네온 효과, 카메라에 포스트 프로세서등을 달아 어느 정도의 최적화가 더 필요한지 확인하여 견적을 잡아야겠다.

3. 과제에 대해

탄막의 네온효과, 카메라의 포스트 프로세싱 적용, 실제 게임 중 탄막 사용 예상량 등을 근거로 프레임 저하가 어느 정도 더 일어나는지 확인한다. 이후 견적을 내어 필요한 만큼의 최적화를 진행. 다만 후순위 작업이 될 것이고, 패턴의 다양화를 위한 추가 스크립팅을 하는 것을 우선으로 한다.

일단 Sphere 형태같이, 동시 여러 방향에 탄막을 사용하는 패턴을 구사

반응형