
안영훈 포트폴리오 (상위 링크로 되돌아가기)
| 제목 | 디버그 (Debug) |
|---|---|
| 개발 기간 | 2024.07.02 ~ 2024.08.28 (약 2개월) |
| 인원 | 3인 (개발, 기획 겸직) |
| 깃허브 | ‣ |
| 장르 | 2D, 생존, 탄막, 1인 플레이, 로그라이크 |
| 개발 환경 | Unity 2D, C#, Git Kraken |
| • 핵심 로직 | |
|---|---|
| 싱글톤 패턴 기반 전역 매니저 객체 설계 | 게임 상태, 사운드, 재화 등 주요 데이터를 중앙 집중식 관리 |
| 추상 클래스 기반 무기/발사체 시스템 설계 | 상속 구조를 활용하여 다양한 무기를 확장성 있게 관리 및 구현 |
| • 게임 플레이 및 콘텐츠 | |
| Unity Input System을 활용한 플레이어 조작 | UI 제어, 플레이어 조작 등 다양한 상태의 사용자 입력 처리 |
| 보스 몬스터 패턴 및 기믹 | 위치 데이터 버퍼 기반의 뱀 형태의 움직임을 가진 보스 구현 |
| 아이템 획득 로직 구현 | 충돌과 자석 효과를 이용한 아이템 획득 구현 |
뱀 형태 보스 몬스터 구현
| 문제 상황 | 1. 위치 데이터를 프레임 종속적으로 저장합니다 (FixedUpdate) 2. 가변 리스트에서 위치 데이터를 관리하고 있습니다. (List<>) 3. 삼각함수는 무거운 연산이라 비효율적입니다. | | --- | --- | | 발생한 한계 | 1. 프레임 드랍 등의 하드웨어 환경에 따라 품질이 균질하지 않습니다 2. 사용한 위치 데이터를 RemoveAt(0) 하여 관리하므로 매 프레임마다 O(N)의 비효율이 발생했습니다 3. 매번 충돌이 발생할 때마다 비싼 삼각함수 연산이 호출됩니다. | | 깨달음 및 개선 | 개발자는 플레이어가 환경에 구애 받지 않도록 노력해야 합니다. 위 문제를 지금 개선한다면 다음과 같이 할 것입니다.
• 거리 기반 위치 데이터 저장
프레임 종속이 아닌 거리 기반으로 개선하는 것이 좋습니다. 일정 거리 이상 움직이면 저장하는 방식이면 하드웨어 환경에 구애 받지 않고 움직임을 구현할 수 있습니다. 대신 초기에 위치 데이터가 충분히 쌓이지 않을 수 있으므로, 초기화를 시켜두거나 early return으로 데이터가 모일 때까지 대기 시키는 방법이 있습니다.
• 링 버퍼 사용
뱀의 길이가 일정하므로 가변 리스트 대신 링 버퍼를 사용할 수 있습니다. 데이터를 삭제하지 않고 덮어 씌우는 방식으로 관리할 수 있으며, 안정적으로 O(1)에 데이터를 참조 가능합니다.
• Vector 기반의 연산
비싼 삼각함수 대신, Unity Collision이 제공하는 Vector 연산을 활용하면 쉽고 가볍게 구현할 수 있습니다. 법선 벡터에 뱀의 움직임 벡터를 내적하면 삼각함수를 쓰지 않고도 요소 벡터를 얻어낼 수 있습니다. |
상속 패턴 경직성
public abstract class PlayerWeapon : MonoBehaviour
{
/ * (중략) */
// auto fire
protected abstract void Fire();
// need to click
public abstract void Fire(InputAction.CallbackContext context);
}
| 문제 상황 | 무기 시스템을 추상 클래스 하나로 묶어 자동 발사와 클릭 발사 함수를 모두 abstract로 선언하여 오버로딩 했습니다. |
|---|---|
| 발생한 한계 | 이 설계로 인해 자동 발사만 하는 무기와 클릭 발사만 하는 무기 양쪽 다 자신이 쓰지 않는 Fire 함수를 빈 함수로 구현해야 하는 코드의 경직성과 낭비가 발생했습니다. |
| 깨달음 및 개선 | 이론적인 상속 구조의 얽메여 억지로 부모 클래스에 기능을 넣는 것은 좋지 않습니다. 그러나 부모 클래스를 추가로 만들자니 코드 중복이 발생합니다. |
만약 다시 설계한다면 IAutoFire, IClickFire과 같이 인터페이스를 상속하게 하여 컴포지션 방식으로 바꾸어 결합도를 낮추고 유연성을 확보할 것입니다. |
개발 과정) 유니티 프로파일러를 활용한 메인 스레드 무한 루프 디버깅
| 문제 상황 | 유저의 레벨이 오를 때 게임이 멈추고 아무런 입력이 되지 않는 문제가 발생했습니다. |
|---|---|
| 발생한 한계 | 처음에는 단순한 과부화나 유니티 엔진 자체의 문제인 줄 알았으나, 음악은 제대로 작동 중이었습니다. 이는 서브 스레드는 잘 작동 중이고 메인 스레드에서 문제가 있음을 시사 했습니다. |
| Visual Studio의 연동 디버깅 Break Point와 유니티 프로파일러를 ****사용하여 확인한 결과, GameManager 로직의 while문 내부에서 무한 반복을 일으키는 특정 분기가 존재함을 확인 했습니다. | |
| 깨달음 및 개선 | 해당 while문의 문제가 되는 분기의 로직을 수정하여 정상 작동하도록 변경했습니다. |
이 경험을 통해 유니티 엔진이 단일 스레드 기반으로 동작하여, 무한 루프로 인해 프레임 렌더링 전체를 마비시킬 수 있음을 깨달았습니다. 이후 while문을 사용할 때 무한 루프 사용을 최소화하고 불가피하다면 분기와 조건을 꼼꼼히 체크하는 등 방어적인 설계 습관을 들이게 되었습니다. |