# Refactor Plan 스크립트가 커진 이유와 앞으로 나눌 구조를 정리합니다. 이 문서는 실제 리팩터링 기준과 진행 상태를 함께 정리합니다. ## 목표 현재 목표는 기능을 바꾸는 것이 아니라 책임을 분리하는 것입니다. - `GameFlowManager`는 화면 흐름만 관리 - `GameManager`는 플레이 세션의 큰 흐름만 관리 - 화면 UI는 화면별 View 클래스로 분리 - 맵 데이터는 맵별 파일로 분리 - 코스 패턴은 튜토리얼 전용과 일반 맵 전용으로 분리 - `PlatformSpawner`는 코스를 직접 정의하지 않고 받은 코스만 실행 ## 현재 문제 ### GameFlowManager 현재 `GameFlowManager`가 담당하는 일이 너무 많습니다. - 씬 흐름 - 저장 데이터 처리 - 결과 화면 UI 생성 - 면세점 UI 생성 - 인트로 UI 생성 - 맵 프리뷰 UI 생성 - 디버그 메뉴 - 공통 UI 오브젝트 생성 - 이미지/스프라이트 로딩 최종적으로는 흐름 제어만 남기고 화면 생성 코드는 `Flow/Screens`로 옮깁니다. ### GameManager 현재 `GameManager`도 플레이와 UI가 섞여 있습니다. - 게임 시작/종료 - 거리/시간/점수 계산 - 목숨/피격/무적 - 아이템 효과 - 튜토리얼 설명창 - 왼쪽/오른쪽 HUD - 도착 게이트 생성 - 코스 미니맵 내부 클래스 최종적으로는 플레이 세션 관리만 남기고 HUD, 튜토리얼, 도착 게이트, 아이템 효과를 분리합니다. ### Map / Course `PlatformSpawner.TutorialStep`은 독립 `CourseStep` 타입으로 분리했습니다. 맵별 생성 코드는 `Maps/Definitions/*Map.cs`로 분리했습니다. 아직 코스 배열은 `CourseProfile`로 묶이지 않고 `openingSteps`, `loopSteps`로 직접 연결되어 있습니다. 최종적으로는 `CourseProfile`을 독립 타입으로 만들고, 맵은 코스 프로필만 참조하게 합니다. ## 목표 폴더 구조 ```text Assets/Scripts ├─ Flow │ ├─ GameFlowManager.cs │ ├─ FlowScreen.cs │ ├─ FlowScreenContext.cs │ ├─ Screens │ │ ├─ IntroScreenView.cs │ │ ├─ OpeningStoryScreenView.cs │ │ ├─ ResultScreenView.cs │ │ ├─ DutyFreeShopView.cs │ │ ├─ MapPreviewScreenView.cs │ │ └─ DebugMenuView.cs │ └─ UI │ ├─ FlowUiFactory.cs │ └─ FlowAssetLoader.cs │ ├─ Gameplay │ ├─ GameManager.cs │ ├─ GameplaySession.cs │ ├─ StageProgressTracker.cs │ ├─ FinishGateController.cs │ ├─ ItemEffectController.cs │ └─ DamageController.cs │ ├─ Gameplay/UI │ ├─ GameplayHudView.cs │ ├─ TutorialGuideController.cs │ ├─ TutorialGuideView.cs │ └─ CourseMinimapView.cs │ ├─ Maps │ ├─ MapId.cs │ ├─ MapDefinition.cs │ ├─ MapDatabase.cs │ └─ Definitions │ ├─ TutorialIncheonMap.cs │ ├─ JapanMap.cs │ ├─ ChinaMap.cs │ └─ AmericaMap.cs │ └─ Course ├─ CourseStep.cs ├─ CourseStepKind.cs ├─ CoursePlatformType.cs ├─ CourseStepFactory.cs ├─ CourseProfile.cs ├─ TutorialCourseProfile.cs ├─ JapanCourseProfile.cs ├─ ChinaCourseProfile.cs └─ AmericaCourseProfile.cs ``` ## 책임 분리 기준 ### Flow `GameFlowManager`는 다음만 담당합니다. - 현재 화면 상태 - 씬 이동 - 저장 데이터 로드/저장 - 게임 시작 요청 - 결과 화면으로 이동 - 다음 맵 선택 화면 구성은 각 View가 담당합니다. | 화면 | 분리 대상 | | --- | --- | | Intro | `IntroScreenView` | | Opening Story | `OpeningStoryScreenView` | | Result | `ResultScreenView` | | DutyFreeShop | `DutyFreeShopView` | | MapPreview | `MapPreviewScreenView` | | Debug Menu | `DebugMenuView` | 공통 UI 생성은 `FlowUiFactory`, 에셋 로딩은 `FlowAssetLoader`로 옮깁니다. ### Gameplay `GameManager`는 플레이 세션의 큰 흐름만 담당합니다. | 책임 | 분리 대상 | | --- | --- | | 거리/시간/클리어 판정 | `StageProgressTracker` | | 도착 게이트 생성/정리 | `FinishGateController` | | 목숨/피격/무적/방어막 | `DamageController` | | 아이템 효과 | `ItemEffectController` | | 왼쪽/오른쪽 HUD | `GameplayHudView` | | 튜토리얼 안내창 표시 | `TutorialGuideView` | | 튜토리얼 단계 제어 | `TutorialGuideController` | | 코스 미니맵 | `CourseMinimapView` | ### Maps / Course 맵 데이터와 코스 실행을 분리합니다. 현재: ```text MapDefinition -> CourseStep[] -> Maps/Definitions/*Map.cs가 맵별 코스 배열을 직접 생성 -> PlatformSpawner가 fallback 패턴도 직접 생성 ``` 목표: ```text MapDefinition -> CourseProfile -> CourseStep[] -> PlatformSpawner는 CourseStep을 실행만 함 ``` 튜토리얼과 일반 맵은 역할이 다릅니다. | 코스 | 역할 | | --- | --- | | `TutorialCourseProfile` | 조작 학습, 강제 피격, 아이템 체험, 실전 연습 | | `JapanCourseProfile` | 첫 일반 맵, 쉬운 반복 패턴 | | `ChinaCourseProfile` | 간격 변화와 슬라이드/점프 확장 | | `AmericaCourseProfile` | 빠른 속도와 후반 난이도 | ## 진행 순서 1. 완료: `CourseStep` 분리 - `PlatformSpawner.TutorialStep`을 독립 파일로 이동 - `TutorialStep` 이름을 `CourseStep`으로 변경 - `CourseStepKind`, `CoursePlatformType`도 독립 파일로 이동 - 남은 이름 정리는 `CourseProfile` 분리 때 함께 진행 2. 완료: 맵 정의 파일 분리 - `MapDatabase.cs`는 목록 관리만 담당 - `TutorialIncheonMap`, `JapanMap`, `ChinaMap`, `AmericaMap`으로 나눔 3. 다음: 코스 프로필 분리 - 튜토리얼 코스와 일반 맵 코스를 각각 `CourseProfile`로 분리 - 일본, 중국, 미국은 튜토리얼 패턴을 복붙하지 않음 4. `GameFlowManager` 화면 View 분리 - 결과 화면, 면세점, 디버그 메뉴부터 분리 - 위치 조정 중인 UI 값은 유지한 채 파일만 나눔 5. `GameManager` UI/진행 분리 - HUD와 튜토리얼 안내창을 먼저 분리 - 이후 도착 게이트, 아이템, 피격 처리 분리 6. 검증 - 각 단계마다 `dotnet build Assembly-CSharp.csproj` - Unity Play 모드에서 `Esc` 디버그 메뉴로 화면 확인 - 튜토리얼, 일본, 중국, 미국 맵 진입 확인 ## 주의 사항 - 기능 변경과 파일 분리를 동시에 많이 하지 않습니다. - UI 위치 조정이 끝난 화면은 좌표를 유지한 채 View로 옮깁니다. - 맵별 난이도 조정은 코스 구조 분리 후 진행합니다. - 삭제보다 이동을 우선하고, 빌드가 깨지지 않는 작은 단위로 진행합니다.