내일배움캠프_언리얼9기

내일배움캠프 50일차 TIL 2026/07/02

begin-play 2026. 7. 2. 23:31

TIL - UML 설계를 만들어가는 과정 (스킬/몬스터 구조)

1. 시작 단계: “기능을 그대로 클래스화”

처음에는 보통 이렇게 시작합니다.

  • 쿠파 공격
  • 해골 공격
  • 고블린 공격
  • 플레이어 스킬

👉 이 단계에서는 각 기능을 그대로 클래스로 만듦

예:

  • FireBallAttack
  • PoisonAttack
  • SkeletonAttack

문제 발생

👉 중복이 많아짐

  • 공격 애니메이션 재생 코드 반복
  • 이펙트 재생 반복
  • 사운드 재생 반복
  • 쿨타임 로직 반복

2. 두 번째 단계: “공통 기능 찾기”

여기서 UML 설계의 핵심 사고가 들어감:

“이거 다 똑같이 반복되는데 하나로 묶을 수 없나?”

찾아낸 공통 요소:

  • Attack()
  • Animation Play
  • Effect Play
  • Sound Play
  • Cooldown

👉 그래서 부모 클래스를 생각하게 됨


3. 세 번째 단계: “부모 클래스 도입”

공통 기능을 묶어서 구조를 정리함

EnemyAttack (부모)
 

이때 사고 방식:

  • “변하지 않는 것 → 부모”
  • “변하는 것 → 자식”

4. 네 번째 단계: “차이점 기준으로 분리”

이제 클래스 기준이 “기능 이름”이 아니라

👉 “행동 방식 차이”로 바뀜

예:

몬스터차이
Goomba 돌진
Skeleton 투사체
Slime 점프
Boss 패턴 + 광역

👉 그래서 클래스 구조가 이렇게 바뀜

EnemyAttack
   ↓
Goomba / Skeleton / Slime / Boss
 

5. 다섯 번째 단계: “중간 계층 필요 여부 판단”

여기서 중요한 설계 판단이 나옴

질문:

“NormalMonsterAttack 같은 중간 클래스가 필요한가?”

결론 기준:

  • 공통 로직 많다 → 필요
  • 공통 거의 없다 → 불필요

👉 결과:

  • 보통은 바로 EnemyAttack → 각 몬스터로 감

6. 여섯 번째 단계: “데이터 vs 기능 분리”

여기서 UML 퀄리티가 확 올라감

예:

나쁜 방식

  • FireBallAttack()
  • AcidBallAttack()

좋은 방식

  • ProjectileAttack() 하나
  • projectileClass로 구분

👉 핵심 사고:

“행동은 하나로, 차이는 데이터로”


7. 일곱 번째 단계: “액터 분리 사고 (중요)”

여기서 Unreal 구조로 넘어감

질문:

“투사체는 누가 책임져야 하지?”

결론:

  • 몬스터 → “생성만”
  • Projectile → “이동/충돌/폭발”

👉 책임 분리

BossAttack → Projectile 생성
Projectile → 움직임/충돌 처리
 

8. 여덟 번째 단계: “상속 깊이 정리”

최종적으로 구조를 정리할 때 사고 방식:

  • 너무 깊으면 안 좋음
  • 의미 없는 중간 클래스 제거

👉 그래서 최종 구조는 보통 이렇게 단순화됨

EnemyAttack
   ↓
BossAttack / MonsterAttack
   ↓
Concrete Boss / Monster
   ↓
Projectile (별도 계층)
 

9. 핵심 설계 사고 정리

UML을 그릴 때 실제로 중요한 건 코드가 아니라 “생각 방식”입니다.

핵심 4가지

1)

반복되면 부모로 묶는다


2)

차이는 클래스가 아니라 데이터로 먼저 해결한다


3)

책임이 다르면 클래스도 분리한다
(몬스터 vs 투사체)


4)

중간 클래스는 “진짜 공통이 있을 때만” 만든다


10. 최종 결론

이번 설계 전체 흐름 한 줄 요약:

“기능을 그대로 클래스화 → 중복 발견 → 공통 추출 → 데이터 분리 → 책임 분리 → 구조 단순화”