Optimize - 탄막 구형 패턴 및 대량 탄막

담당자
이도현
상태
Done
시작-완료일
2024/03/13
예정 마감일
2024/03/15
완료일
2024/03/15

개요

탄막이 여러가지 모양과 움직임을 가질 수 있도록 SO와 로직을 확장하고, 다양한 패턴 프리셋과 페이즈셋을 마련한다.

히스토리

03.13

다시금 느끼지만 새벽능률이 미친 것 같다. 취준 입장에선 약점. 낮져밤이 스타일

금일 예정

Linear 패턴은 완료하였고, 구형 패턴을 위한 로직을 작성 할 것이다.
PatternSO를 Inspector에서 더 보기 좋게 Header를 작성할 것이다.
조건에 따라 SO의 Inspector에서 보여지거나 보여지지 않을 필드를 고려하여 표시할 수 있지만, 이전 구현 중 이러저런 이슈가 있어 쉽지는 않을 것으로 보인다.
Linear 패턴은 완료, 구형 패턴을 위한 로직을 작성 + 알파
PatternSO를 Inspector에서 더 보기 좋게 Header를 작성

03.14

구형 패턴 1차적으로 완성은 했는데, 상하 끝 점에 여러 탄막이 모여있는 등 개선 필요
구형(100개 탄막) → 구형(100배로)으로 연쇄시켰더니 유니티가 터져버렸다. 바보
무튼 대충 테스트를 해 보는데, 아무래도 동시에 탄막을 반환하던가 하는 때에 갑자기 렉이 걸리거나 하는 것이 심하다. 아래는 프로파일러의 결과.
렉 심할 시점의 99프로 CPU 지분을 Pool에의 반환 로직이 먹고 있다.
이를 분산시킬 필요가 있다.
예를들어 반환 시점에 각자 랜덤한 차이를 미세하게 두는 방법.
IEnumerator Co_Release() { yield return new WaitForSeconds(_currentParameters.releaseTimer); ReleaseObject(); }
C#
복사
기존 위와 같았던 코드의 Timer에 랜덤값을 더한다.
… 를 생각했지만
배치 처리: 동시에 반환되는 탄막의 수를 제한하고, 반환을 여러 프레임에 걸쳐 배치 처리할 수 있다. 이렇게 하면 한 번에 발생하는 부하를 분산시켜 프레임 드롭을 줄일 수 있다. 이러한 방법이 있다고 한다. 풀 매니저에 큐를 두어, 프레임마다 일정 수량만큼만 반환되도록 한다.
private Queue<GameObject> releaseQueue = new Queue<GameObject>(); private int releaseBatchSize = 30; // 한 프레임에 반환할 오브젝트 수 private void Update() { ProcessReleaseQueue(); } private void ProcessReleaseQueue() { for (int i = 0; i < releaseBatchSize && releaseQueue.Count > 0; i++) { GameObject go = releaseQueue.Dequeue(); // 안전 검사: 오브젝트가 아직 활성화 상태인지 확인 if (go.activeInHierarchy) { go.SetActive(false); // 비활성화하거나 반환 로직 수행 // 실제 풀로 반환 처리 } } }
C#
복사
이런 느낌으로 사용. 이 방법으로 해결할 수 있다는 확신이 들어 바로 구현했다.
반환 쪽 성능이 그래프에 나타나지도 않을 정도로 깔끔해졌다.
현재 남아 있는 고점은, 풀에서 오브젝트를 활성화하는 시점들이다. 그래도 반환 시에 2000ms 전후를 찍었던 것에 비해 생성 쪽은 60~200ms의 지연밖에 없긴 하다.
반환쪽 문제를 배치처리로 해결한 시점의 시연
많은 탄막을 생성하는 시점만 빼면 봐 줄 수 있을 정도의 속도가 되었다. 정말 10배 이상은 더 길게 멈칫멈칫했는데 정말 다행인 부분.
그리고 생성에도 똑같이 위와 같은 배치 처리를 사용 할 수 있을 것으로 보여 바로 로직을 바꿔보자고 생각했다. 다만 탄환의 반환보다 훨씬 어색해 보일 수 있다는 것은 조심해야 할 사항이다.
생성쪽에도 바로 사용 해 보자.
경과 : 생성 쪽의 배치처리 저녁까지 시도했지만 잘 풀리지 않음… ‘없는’것, 그리고 ‘Active’ 상태가 아닌 것에 이런 저런 처리를 하려고 하니 쉽게 될리가 만무. 지금 생각한 방안 중 남은 시도 할 수 있는 건, PoolManager쪽에 새로운 탄막의 위치/방향/세팅 정보를 같이 넘겨 생성완료 시 이를 적용하는 방법인데, 이러면 정말로 디럭스 스파게티가 됨.
배치방식을 PoolManager가 아닌, Generator에 한 번 적용해봄은 어떨지? → 어… 진짜 당장 보기엔 장애물은 없어 보이긴 하는데..? 바로 해볼까? 그래도 Pool이랑 다른 곳에 배치처리가 구현된다는 점은 단점이기는 함.
일단 패턴쪽을 수습합시다

03.18

망한 코드
어떻게든 리스트 형태의 박스에 넣어서 관리(토글기능 및 요소 순서 교체) 하고 싶었지만 별 짓을 다해도 안되어서 아래와 같은 형태에 일단 만족
패턴 당 토글을 통해 열어 관리가 가능하다.
현재 문제점은 Enemy쪽이 이 탄막을 실시간으로 편하게 관리할 수가 없다는점.(시작과 종료만이 가능하고 재사용이 불가능하다.
그리고, 수명 ≠ 다음 연쇄패턴시작 이라서, 페이즈를 짤 때 시간 설정을 수동으로 각각 맞춰줘야 한다는 점이다. 개선을 빠르게 가능할지 모르겠음.