MOONSUN
[UE5] Animation Montage(몽타주) : 콤보 공격 구현 본문
이전 글에서 StateMachine으로 애니메이션을 전환 했었는데,
만약 4개의 공격 애니메이션이 있고,
연속으로 공격 명령을 내리면 콤보 공격처럼 각 공격 애니메이션을 순서대로 연계해야 한다면?
Attack1 → Attack2 → Attack3 → Attack4 ...
이전처럼 StateMachine 방식으로 관리한다면
→ 상태/전이 관리가 매우 복잡해져서, 스테이트 머신 설계가 복잡해지는 단점이 있다.
⇒ 스테이트 머신의 확장 없이 특정 상황에서 원하는 애니메이션을 발동 시키는 애니메이션 몽타주 라는 기능이 있다!
Animation Montage 란?
StateMachine을 건드리지 않고 특정 애니메이션을 실행한다.
- 원하는 타이밍에 재생 가능
- 순차 연결(콤보) 구현 가능
- 이벤트(Notify) 기반 제어 가능
애니메이션 3개 가지고 콤보 공격 만들어보자.
Attack1 → Attack2 → Attack3 (콤보)
- 공격 타이밍 맞으면 → 다음 공격 이어짐
- 타이밍 놓치면 → 콤보 끊기고 처음으로 돌아감
1. 콤보 시스템 전체 구조
입력 → 캐릭터 코드 → AnimInstance → Montage → Section 이동
- 입력은 Character에서 처리
- 애니메이션 제어는 Montage가 담당
- 실제 흐름 제어는 Section 이동으로 처리
2. 몽타주 구성 (Sections)

Attack1 → Attack2 → Attack3
- 애니메이션 3개를 Montage에 배치 (지그재그로 들어감)

2. 각 애니메이션을 Section으로 분리
- 각 애니메이션들은 Section으로 분리해서 처리할 수 있다.
- 오른쪽에는 기본적으로 Section별로 자동 연결된 걸 볼 수 있음

- Section끼리 연결 끊기.

왜? → 콤보는 “조건부로 다음 섹션으로 이동”해야 하기 때문
(연결되어있으면 자동으로 넘어가니까..)
Character 에 몽타주 추가

4. 몽타주 재생 (Character 코드)
이제 공격 입력이 들어오면 Montage를 재생하도록 구현한다.
먼저, Attack을 위한 IA와 IMC를 추가한 뒤, 입력 바인딩을 설정한다.


입력 바인딩
EIC->BindAction(IA_Attack, ETriggerEvent::Triggered,this, &ATPSPlayer::PlayAttackMontage);
Montage 재생 함수
void ATPSPlayer::PlayAttackMontage()
{
UAnimInstance*AnimInstance = GetMesh()->GetAnimInstance();
if (AnimInstance&&AttackMontage)
{
AnimInstance->Montage_Play(AttackMontage);
}
}
(중요) Montage는 AnimInstance를 통해 재생해야 한다
5. AnimGraph 설정 (Slot 추가)
Montage는 Slot을 통해서만 출력에 반영된다
StateMachine → Slot → Output Pose
(우리는 모든 상황에서 몽타주를 재생할 거라서 Output Pose와 StateMachine 사이에 몽타주 재생 노드 추가)


- StateMachine가 기본 포즈 생성
- Montage는 중간에 끼어들어 애니메이션을 덮어쓴다.
즉, Slot이 없으면 Montage는 재생되어도 화면에 안 보임
8. 입력 처리 로직 (Character → AnimInstance)
void ATPSPlayer::PlayAttackMontage()
{
UAnimInstance*AnimInstance =GetMesh()->GetAnimInstance();
if (!AnimInstance||!AttackMontage)return;
// 몽타주가 이미 실행 중인지 확인
if (AnimInstance->Montage_IsPlaying(AttackMontage))
{
// 이미 공격 중이면 → 콤보 입력만 저장
UABAnimInstance*ABAnim =Cast<UABAnimInstance>(AnimInstance);
if (ABAnim)
{
ABAnim->bComboInput =true;
}
}
else
{
// 첫 공격 시작
AnimInstance->Montage_Play(AttackMontage);
UABAnimInstance*ABAnim =Cast<UABAnimInstance>(AnimInstance);
if (ABAnim)
{
ABAnim->CurrentCombo =1;
}
}
}
흐름
공격 중 → 입력 → 예약 (bComboInput)
공격 아님 → 첫 공격 시작
9. Notify로 콤보 타이밍 제어
콤보는 Notify로 제어한다
Notify 역할
| Notify | 역할 |
| ComboWindowOpen | 입력 가능 시작 |
| ComboWindowClose | 입력 가능 종료 |
Notify 위치
Open : 60~70%
Close : 85~95%
(너무 뒤에 두면 입력 씹힘 이슈 발생.. )
아래처럼 Notify를 추가했다.


(중요) Notify 종류
Montage Notify
- C++ 함수로 안 들어올 수 있음
올바른 방식
Add Notify → New Notify...
이름
ComboWindowOpen
ComboWindowClose
규칙
AnimNotify_이름
함수 이름과 정확히 일치해야 호출됨
10. Notify 함수 구현 (AnimInstance)
void UABAnimInstance::AnimNotify_ComboWindowOpen()
{
bCanNextCombo =true;
}
void UABAnimInstance::AnimNotify_ComboWindowClose()
{
bCanNextCombo =false;
// 입력이 들어왔으면 다음 콤보 진행
if (bComboInput)
{
bComboInput =false;
CurrentCombo++;
FNameNextSection =FName(*FString::Printf(TEXT("Attack%d"),CurrentCombo));
Montage_JumpToSection(NextSection);
}
}
로직
1. 입력은 미리 저장됨
2. 타이밍이 열리면 (Open)
3. 닫힐 때 (Close)
→ 입력 있으면 다음 섹션 이동
11. OnMontageEnded (상태 초기화)
콤보 종료 시 상태 초기화
void UABAnimInstance::OnMontageEnded(UAnimMontage*Montage,boolbInterrupted)
{
bCanNextCombo =false;
bComboInput =false;
CurrentCombo =0;
}
12. 전체 콤보 흐름
입력
↓
Montage 시작 (Attack1)
↓
Notify Open
↓
입력 저장
↓
Notify Close
↓
조건 만족 → 다음 Section (Attack2)
↓
반복
↓
끝나면 초기화
정리
공격 버튼을 누르면 몽타주를 재생하고, 공격 중에 다시 입력이 들어오면 그 입력을 저장해뒀다가,
Notify 타이밍에 다음 Section으로 넘겨서 콤보를 이어가라는 뜻
1. 몽타주를 만든다
- Attack1, Attack2, Attack3 애니메이션을 하나의 Montage에 넣기
- 각 구간을 Section으로 나누기
- Section 자동 연결은 끊기
2. 공격 입력을 받으면 몽타주를 재생한다
- 공격 중이 아니면 Montage_Play()로 시작
- 첫 시작은 Attack1
3. 공격 중에 다시 입력이 들어오면 바로 재생하지 말고 “예약”만 한다
- 예를 들어
- bComboInput = true 이렇게 저장만 해둠
4. 각 공격 애니메이션 중간에 Notify를 넣는다
- ComboWindowOpen : 지금부터 다음 공격 입력 받아도 됨
- ComboWindowClose : 이제 입력 마감
5. ComboWindowClose 시점에 예약된 입력이 있으면 다음 Section으로 이동한다
- Attack1 재생 중, 플레이어가 한 번 더 입력하면
- bComboInput = true
- ComboWindowClose 도착 → Attack2로 Montage_JumpToSection()
6. 입력이 없으면 콤보를 끝낸다
- Attack1만 하고 종료
- 몽타주 끝나면 상태 초기화
'UE5' 카테고리의 다른 글
| [UE5] 공격 물리 판정 구현 2 : AnimNotify + AnimInstance Delegate 방식 (0) | 2026.04.09 |
|---|---|
| [UE5] 공격 물리 판정 구현 1 : 콜리전 채널 + 트레이스 채널 세팅 (1) | 2026.04.09 |
| [UE5] 언리얼 리타겟팅(Retargeting) : UE5.6 기준 (0) | 2026.04.03 |
| [UE5] 언리얼 애니메이션 StateMachine 설계와 Jump 구현 (0) | 2026.04.03 |
| [UE5] 언리얼 애니메이션 구조 이해: AnimInstance와 AnimGraph (0) | 2026.04.03 |
