Skip to content

Latest commit

 

History

History
269 lines (218 loc) · 7.58 KB

File metadata and controls

269 lines (218 loc) · 7.58 KB

ProjectBB Development Guidelines

프로젝트 개요

ProjectBB는 데브 더 다이버 형식의 2D 타이쿤 게임입니다.

  • 플레이어가 요리 미니게임을 통해 요리를 완성
  • 결과에 따라 평가 및 수익 생성
  • 다양한 시스템으로 확장 가능한 구조

개발 원칙

1. 아키텍처

  • 상속 중심: 베이스 클래스를 통한 공통 기능 구현
  • 매니저 패턴: 기능별 Manager 클래스로 중앙 관리
  • 컴포넌트 기반: MonoBehaviour 상속으로 모듈화

2. 네이밍 규칙

  • 클래스: PascalCase (GameManager, InputManager, CookingComponent)
  • 메서드: PascalCase (StartMiniGame, OnInteract)
  • 필드 (Private): camelCase 또는 _camelCase (currentAngle, _moveInput)
  • 필드 (Public): PascalCase (IsPlaying, MoveInput)
  • 상수: UPPER_SNAKE_CASE (MAX_ANGLE = 180f)
  • Enum: PascalCase (ENUMGRADE.GREAT)

3. 주석 정책

  • 최소한의 주석: 복잡한 로직이나 의도가 불명확한 부분에만 사용
  • 자명한 코드: 변수명과 메서드명으로 의도를 명확히
  • XML 주석: public 메서드/클래스에만 선택적으로 사용
  • 예시:
    // Good: 변수명이 의도를 명시
    float distanceToEndpoint = Mathf.Min(currentAngle, MAX_ANGLE - currentAngle);
    
    // 지양: 불필요한 주석
    // endPoint까지의 거리
    float d = Mathf.Min(a, b);

4. 상속 활용

  • 베이스 클래스: 공통 기능 및 생명주기 정의
    • CookingComponent: 모든 요리 미니게임의 부모 (Interact, JudgeResult 등)
    • Manager: 각 기능별 Manager의 베이스 (필요시 추가)
  • 메서드 오버라이드: protected override로 자식에서 구현
  • 가상 메서드: protected virtual로 선택적 확장 지원

프로젝트 구조

Assets/Scripts/
│
├── GamePlay/              (게임 진행 관련)
│   ├── GameManager.cs     - 게임 전체 로직 및 상태 관리
│   ├── InputManager.cs    - 입력 처리 및 액션맵 전환
│   ├── SceneManager.cs    - 씬 전환 관리
│   ├── MainCharacter.cs   - 플레이어 캐릭터
│   ├── TimelineHandler.cs - 타임라인 연출
│   ├── TimelineBase.cs    - 타임라인 베이스
│   └── [새로운 Manager들 추가 예정]
│
├── Cooking/               (미니게임 요리 시스템)
│   ├── CookingComponent.cs       - 미니게임 베이스 클래스 (추상)
│   │   └── 자식 구현 메서드:
│   │       - InitCooking()
│   │       - Interact()
│   │       - JudgeResult()
│   │       - EndMiniGame()
│   ├── CookingTimerComponent.cs  - 타이머 UI
│   ├── CuttingComponent.cs       - 자르기 미니게임 (상속)
│   └── BoilingComponent.cs       - 끓이기 미니게임 (상속)
│
├── Data/                  (데이터 관리)
│   ├── DataManager.cs     - 데이터 전체 관리
│   ├── SaveSystem.cs      - 저장/로드 시스템
│   ├── FileManager.cs     - 파일 I/O
│   ├── SaveData.cs        - 저장 데이터 구조
│   ├── DataDrivenDefines.cs   - 게임 설정값
│   ├── DataEnumDefines.cs     - 게임 열거형
│   └── ParsingHelper.cs   - XML/데이터 파싱
│
├── MainTimeline/          (메인 씬 연출)
│   └── [타임라인 관련 에셋]
│
└── [새로운 폴더 예정]

주요 클래스 역할

CookingComponent (베이스)

public abstract class CookingComponent : MonoBehaviour
{
    protected abstract void InitCooking();      // 각 미니게임 초기화
    protected abstract void Interact();         // 플레이어 상호작용
    protected abstract void JudgeResult();      // 결과 판정
    protected abstract void EndMiniGame();      // 미니게임 종료
}

특징: 모든 하위 미니게임이 공통 생명주기 따름

InputManager

  • Default ↔ Minigame 액션맵 전환 담당
  • 모든 입력을 일원화
  • SwitchActionMap(string actionMapName) 제공

GameManager

  • 게임 전체 상태 관리
  • 시스템 간 통신 중심
  • Singleton 패턴 활용 권장

DataManager

  • XML 데이터 로드/파싱
  • 런타임 데이터 관리
  • SaveSystem과 협력

개발 흐름

새 미니게임 추가 시

1. Cooking 폴더에 새 Component 클래스 생성
   └─ CookingComponent 상속
   
2. 필수 메서드 구현
   ├─ InitCooking()
   ├─ Interact()
   ├─ JudgeResult()
   └─ EndMiniGame()
   
3. 각 미니게임의 고유 로직 작성
   └─ 기본 생명주기는 CookingComponent에서 관리
   
4. InputManager의 액션맵 전환 자동 적용됨

새 Manager 추가 시

1. GamePlay 폴더에 Manager 클래스 생성
2. 기능 모듈화 및 공개 인터페이스 정의
3. 싱글톤 또는 찾기 패턴으로 접근
   └─ FindFirstObjectByType<ManagerName>()

입력 시스템 (Input Action System)

액션맵 구조

Default          - 일반 게임플레이
├─ Move          - 캐릭터 이동
└─ Interact      - 상호작용

Minigame         - 미니게임 모드
├─ Game_Move     - 미니게임 조작
└─ Game_Interact - 미니게임 상호작용

전환 흐름

게임 시작 → Default 액션맵
   ↓
미니게임 시작 → Minigame 액션맵 (자동 전환)
   ↓
미니게임 종료 → Default 액션맵 (자동 복원)

담당: CookingComponent.OnTimerComplete() / OnGameEnd()


코드 스타일 예시

✅ Good

private float GetInputAngleChange()
{
    float distanceToCenter = 90f - Mathf.Abs(currentAngle - 90f);
    float changeMultiplier = distanceToCenter / 90f;
    return interactIncrease * Time.deltaTime * changeMultiplier;
}

protected virtual void OnGameEnd()
{
    FindFirstObjectByType<InputManager>().SwitchActionMap("Default");
    isPlaying = false;
}

if (moveAction == null) return;

if (currentAngle <= MIN_ANGLE || currentAngle >= MAX_ANGLE) 
    return;

❌ Avoid

// 의도 불명확한 약자
private float GetIAC() { ... }

// 과도한 주석
// 90도에서의 거리 계산 (이미 메서드명과 변수명이 명확함)
float d = 90f - Mathf.Abs(a - 90f);

// 불필요한 함수 분리 (1회만 사용)
private float ValidateAngle() => Mathf.Min(currentAngle + angleChange, MAX_ANGLE);

// 긴 if문
if (moveAction != null)
{
    return;
}

코드 작성 규칙

함수 분리

  • 2번 이상 중복되는 로직만 함수로 분리
  • 1회만 사용되는 코드는 인라인 작성
  • 예: 검증, 계산 등의 헬퍼 메서드는 필요시 구현

Early Return 패턴

  • if (조건) return; 형태는 같은 줄에 작성
  • 복잡한 검증은 가독성을 위해 여러 줄 허용

예시

// ✅ Good - Early return
private void UpdateAngle()
{
    if (!isPlaying) return;
    if (moveAction == null) return;

    float distanceToEndpoint = Mathf.Min(currentAngle, MAX_ANGLE - currentAngle);
    float speedMultiplier = 1f + (1f - distanceToEndpoint / 90f);
    currentAngle = ApplyAngleChange(speedMultiplier);
}

// ❌ Avoid - 불필요한 들여쓰기
private void UpdateAngle()
{
    if (!isPlaying)
    {
        return;
    }
    
    if (moveAction == null)
    {
        return;
    }
    
    // ... rest of code
}

향후 확장 예정

  • 게임 저장/로드 시스템 연동
  • 추가 미니게임 (데브더 다이버 풍의 여러 요리법)
  • NPC 및 평판 시스템
  • 마을 경영 UI
  • 사운드 / 이펙트 시스템