오늘도 Unity 팀 프로젝트 작업을 진행했다. 내가 작업하기로 한 내용인 커스터마이징, 도전과제(업적) 시스템을 위한 사전작업을 진행하였고, 피격 시 무적판정 추가, 애니메이터 트랜지션을 다듬었다. 마지막으로 내가 작업한 코드를 기능별로 분리하는 작업을 진행하였다.
도전기능 사전작업
커스터마이징 시스템 사전작업
- 플레이어 프리팹을 생성하고, 각각의 애니메이션을 제작하였다.
- 이후 이를 딕셔너리 형태로 관리하여 게임 진행 정도에 따라 활성화되도록 만들 생각이다.
- 또,
DustParticleControl.ReplaceDust() 메서드로 Dust 파티클을 교체할 수 있도록 만들었다.
- 이 또한 이후 딕셔너리 형태로 관리하여 게임 진행 정도에 따라 해금할 생각이다.
도전과제(업적) 시스템 사전작업
- ScriptableObject 에셋을 정의하는
AchievementData를 작성하고, 에셋을 생성하였다.
AchievementData 에셋은 AchievementManager 안에서 딕셔너리로 관리할 예정이다.
AchievementManager 스크립트의 뼈대를 작성하였다.
- 달성 여부 확인, 진행도 확인 등의 관리를 할 예정이다.
PlayerController에서 도전과제 요소들을 작성했다.
- 달린 거리, 넘은 장애물 수, 장애물에 맞은 횟수, 맞지 않고 장애물을 넘은 횟수 등을 갱신할 수 있도록 만들었다.
리팩토링 트러블 슈팅
배경
- 기존
PlayerController가 너무 많은 기능을 담당하고 있다고 생각했다.
- 이전 개인 프로젝트와 달리 팀 프로젝트를 진행하면서 많은 스크립트를 작성하면 충돌이 생길까봐 하나의 스크립트에서 작성하게 되었다.
- 하지만
PlayerController에서 너무 많은 기능을 담당하다보니 가독성이 떨어지고, 메서드 간 의존성이 늘어나고 유지/보수 측면에서도 불리하다고 생각하게 되었다.
- 이에 각 기능별로 책임을 나눠야겠다는 필요성을 느끼게 되었다.
발단
- 리팩토링의 직접적인 계기는 새로운 기능을 추가하려고 하는 중에 기존 스크립트 구조가 너무 복잡하여 어느 코드에 추가해야할지 헷갈렸다.
- 또한 작은 수정을 할 때에도 전체
PlayerController를 검토해야했고, 이에 디버깅 시간이 늘어났기 때문이다.
전개
- 기존
PlayerController의 기능을 네 개의 스크립트(PlayerMovement, PlayerHealth, PlayerStatusEffects, PlayerCollisionHandler)로 분리하였다.
PlayerMovement는 이동/점프/슬라이드
PlayerHealth는 체력/데미지/사망
PlayerStatusEffects는 무적/속도증가/체력감소 등 시간에 따른 효과들
PlayerCollisionHandler는 트리거 충돌/장애물 감지/콤보,클리어,데미지 등 처리를 담당한다.
PlayerController는 Awake에서 스크립트 참조, Start/Update/FixedUpdate에서는 호출만 담당하도록 만들었다.
위기
- 많은 필드들을 서로 공유하고 있어서 접근 제한자 설정이 어려웠다.
- 몇몇 메서드나 필드명을 옮기는 과정에서 누락되기도 했으며,
- 기존에 있던 기능을 옮기는 과정에서 몇 가지 기능이 누락되기도 했다.
- 예를 들어
GetComponentInChildren<>을 GetComponent<>로 작성하면서 문제가 발생.
절정
- 설상가상으로 작업 후 실행해봤더니 유니티 에디터가 깨지는 현상이 발생했고, 이후 안전 모드로 진입하여 다시 에디터를 실행해보니
GameUI에서 PlayerController에 있는 필드를 참조하고 있어서 "Missing Script"에 의해 발생한 문제라는 것을 깨달았다.
GameUI에서 수정한 스크립트대로 참조를 해주니 정상적으로 작동하였다.
결말
- 씬이 깨끗하게 열리고 각각의 스크립트에 컴포넌트를 할당해주어 플레이어가 의도한대로 작동하였다.
- 앞으로 새로운 기능을 추가하거나 보수가 필요할 때 더욱 쉽게 진행할 수 있겠다는 생각이 든다.
회고 및 느낀점
- 오늘은 리팩토링에 시간을 많이 쏟았던 하루였다.
- 리팩토링 하는 도중, 복잡하더라도 잘 실행되니까 포기하고 이대로 둘까? 하는 생각도 들었다.
- 하지만 기능을 구현하는 것보다는 배우는 것이 중요하다는 생각이 들어 계속 리팩토링을 진행하기로 마음먹었다.
- 개인 프로젝트를 진행할 때는 쉽게쉽게 스크립트를 분리하여 작성했는데, 팀 프로젝트에서는 충돌이 두려워서 스크립트를 쉽게 분리하지 못하는 것 같다.
- 하지만, 오히려 스크립트를 처음부터 분리하여 작성하는 것이 충돌을 막는 방법임을 이번 리팩토링 과정에서 발생한 여러 문제들을 겪으며 깨닫게 되었다.
- 처음부터 스크립트/기능의 흐름을 생각하며 구조를 만들어서 좀 더 효율적인 프로그래밍을 할 수 있도록 해야겠다.