EnemybulletGenerator에 과하게 몰린 코드(튜터님 피드백)

작업자
이도현
Issue.No
8
날짜
2024/03/18
분류
리팩토링
심각도
40
완료
착수
중간발표 끝나면 진짜 밤새서 혼내줄테다 이녀석

2024.04.08

스크립트가 너무 끔찍하여 손대면 꽤 시간이 걸릴 것 같아 EnemyPhaseStarter.cs EnemyBulletGenerator.cs EnemyBulletController.cs 를 GPT에게 넘겨 어떤 분위기인지만 맛보았다.
추천받은 내용 중 중요도 순으로 필요하다고 생각한 것만 적어 보면 아래와 같다.
매개변수 넘기기 간소화
많은 매개변수를 계속해서 넘기는 것 대신, 필요한 데이터를 포함하는 하나의 구조체나 클래스를 사용할 수 있습니다. 예를 들어, EnemyBulletSettings와 같은 클래스에 필요한 모든 설정을 넣고, 이 클래스의 인스턴스만 넘기면 코드가 훨씬 깔끔해집니다.
단일 책임 원칙 적용
각 클래스나 메소드가 하나의 기능만 수행하도록 만드는 것이 좋습니다. 예를 들어, 탄막을 생성하고, 위치를 설정하고, 회전을 적용하는 등의 작업은 분리하여 각각의 클래스나 메소드에서 처리하게 할 수 있습니다.
코루틴 최적화
많은 코루틴이 동시에 실행되면 성능 문제가 발생할 수 있습니다. 가능하면 코루틴의 사용을 줄이고, 특정 이벤트가 발생했을 때만 실행되도록 하거나, Update 메소드 내에서 시간을 체크하여 특정 간격으로 실행되도록 하는 것이 좋습니다.
태그와 레이어 사용 최적화
GameObject.FindGameObjectWithTag와 같은 메소드는 비용이 많이 들기 때문에, 플레이어와 같은 오브젝트를 캐싱하여 사용하는 것이 좋습니다.
(추가) yield return new WaitForSeconds() 사용 줄이기
생각해보니, 위 구문도 상당히 자원을 많이 잡아먹는다고 들어, 팀원이 준비해준 사전형 waitForSeconds로 바꾸어야겠다.
yield return Util.GetWaitSeconds(time);

매개변수 넘기기 간소화

(진행 중 사진)제일 힘들어보일 것 같은 작업. 말도 안되게 많은 매개변수를 통합하자.
과거의 나는 struct보다는 class가 맞나 싶으면서도, 이후 GC에 또 영향을 주기 때문에 struct가 맞나 고민하다가, 그냥 정말 각각의 매개변수를 생으로 넘겨주게 된 흐름이었을지도 모른다.
일단 코드를 보기 좋게 하기 위해 클래스로 통합하자.
이런, 클래스로 묶는 작업을 하고, yield return Util.GetWaitSeconds(time); 구문으로 바꾸어주었는데, 성능이 난리가 났다.
다시 돌아와서, 탄막수 조금 줄여서 다시 테스트를 해 보자.
먼저 WaitForSeconds 를 사용한 경우.
다음, GetWaitSeconds를 사용한 경우
비슷하다. 역시 매개변수들을 모아 클래스화 시킨 게 문제인 것 같다.
일단 뭔가 잘 안되어서 테스트 브렌치로 대피.
현재 상태. 수많은 매개변수를 BulletGenerationSettings로 바꿈.
만악의 근원 발견
FindGameObjectWithTag("Player")
지연 15ms 정도로, 두배가량의 성능개선이 되었다
테스트 씬에서는 Vector3(0,0,20)을 사용했지만, 실제 씬에서는
Managers.Module.CurrentModule.LowerPosition을 사용할 것이다.