Home [UE4] Animation Montage를 사용하여 콤보 공격 구현
Post
Cancel

[UE4] Animation Montage를 사용하여 콤보 공격 구현

UE4의 Animation Montage를 이용하여 콤보 공격을 구현해보자.

Animation 과 Character는 Mixamo를 이용하였습니다.
하나의 Animation으로 되어 있는 콤보 공격 Animation을 사용하였습니다.

1. Animation Montage 란?

언리얼 엔진 문서 - 애니메이션 몽타주

  • Animation Montage를 사용하면 블루프린트 또는 C++ 코드를 통해 Animation Asset을 바로 제어할 수 있다.
  • 여러 애니메이션 시퀀스를 하나의 에셋으로 합칠 수 있고, 여러 섹션으로 나누어 일부 또는 조합 재생이 가능하다.
  • Montage 안에서 이벤트를 발생시켜 사운드 재생, 특정 함수 재생 등 다양한 작업을 할 수 있다.

2. Animation Montage 사용법

Animation Montage 생성

  • Content Browser 에서 우클릭 -> Animation -> Animation Montage 로 생성할 수 있다.

Anim Slot Manager

Animation Montage를 생성해보면 DefaultGroup.DefaultSlot 이란 이름으로 되어 있는데

이름을 바꾸기 위해선 Anim Slot Manger를 통해 바꿀 수 있다.
(만약 Anim Slot Manger 가 보이지 않는다면, 상단 탭 Window에서 활성화할 수 있다.)


Montage Sections

아래 창에서 우클릭을 통해 새로운 Montage Section을 만들 수 있다.

Montage Section 이란,
말 그대로 전체 Montage를 여러 섹션으로 나눌 수 있는 기능이라 볼 수 있는데
Section 이름을 통해 C++ 이나 Blueprint에서 Montage_JumpToSection 이란 메소드로 특정 섹션으로 이동할 수 있다.


Notify

언리얼 엔진 문서 - 애니메이션 노티파이

Notify를 통해 애니메이션 도중 특정 지점에 이벤트가 발생하도록 구성할 수 있다.

공식 문서에 설명이 잘 적혀 있다. 자세한 건 공식 문서에서!!


3. 만들어보자!

어떻게 구현할까?

현재 적용된 애니메이션이 전체 콤보 공격이 들어가 있는 형태이므로 섹션을 굳이 나눌 필요가 없다고 생각했다.

그러므로, 각 공격 애니메이션이 끝나는 타이밍에 Notify를 설정해서

유저가 공격을 이어나갈 시 -> 애니메이션 계속 진행 유저가 공격을 중단할 시 -> 애니메이션 중단

으로 플래그를 나누어 Notify 때 둘 중 하나의 작업이 진행되도록 구현했다.


Animation Montage에 Animation 적용

  • 원하는 Animation을 가져다 놓으면
  • 애니메이션이 적용된 것을 볼 수 있다.

Notify 적용

  • 각 공격 애니메이션이 끝나는 지점에 Notify를 설정해주었다.
  • 총 3번의 공격이 존재하고 마지막 공격은 Notify를 설정할 필요가 없기 때문에 앞의 두 번 공격에 대해서만 설정했다.

C++ 코드

  1. Project Setting -> Engine-Input -> Action Mappings 에 LMB란 이름의 Mapping을 추가

  2. 마우스 왼쪽 클릭을 할 경우 공격 메소드가 실행될 수 있게 코드를 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
// Called to bind functionality to input
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
    
	PlayerInputComponent->BindAction(TEXT("LMB"),IE_Pressed,this, &APlayerCharacter::PressLMB);
}

void APlayerCharacter::PressLMB()
{
	bPressLMB = true;
	Attack();
}
  1. 공격 메소드(Attack()) 구현
    • Mesh -> AnimInstance 에 접근하여 Montage를 플레이해야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void APlayerCharacter::Attack()
{
	if(bAttacking)
	{
		// 연속 공격인지를 확인
		bContinueAttack = true;
	}
	else
	{
		// 공격 중임을 알려준다.
		bAttacking = true;
		
		// 현재 Mesh에서 AnimInstance를 가져오고
		UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
	
		// AnimInstance가 존재한다면,
		if(AnimInstance)
		{
			// Montage를 플레이한다.
			// CombatMeleeAnimMontage: 위에서 만든 Animation Montage를 가진 변수
			AnimInstance->Montage_Play(CombatMeleeAnimMontage);
		}
	}
}

여기까지 구현을 하고 나면 애니메이션은 진행이 되지만, Notify설정이 되지 않아 애니메이션 전체가 재생된다.

  1. Notify 에 연결할 C++ 코드 구현
    • Notify를 blueprint에서 조작할 것이기 때문에 C++ 에서 만든 메소드를 UFUNCTION(BlueprintCallable)를 통해 가져온다.
    • 콤보 공격이 유효한지를 알아내기 위해 DoAttackCombo()라는 메소드를 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void APlayerCharacter::DoAttackCombo()
{
	// 3번에서 bAttacking == true 일 때,
	// 마우스 왼쪽 클릭을 하게 되면 bContinueAttack = true 가 되게 설정하였다.
    
	// 유저가 마우스 왼쪽 클릭을 누르지 않았다면,
	if(!bContinueAttack)
	{
		UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
		
		if(AnimInstance)
		{
			// Montage 종료
			// 1.f는 Montage 애니메이션 중에 Stop될 때
			// 애니메이션이 끊기지 않고 자연스럽게 1초 동안 애니메이션 블랜딩이 되게 한다.
			AnimInstance->Montage_Stop(1.f,CombatMeleeAnimMontage);
		}
	}
	
	// 다음 Notify를 위해 false 설정
	bContinueAttack = false;
}
  1. Notify 설정
    • Animation Blueprint -> Event Graph에서 우클릭 -> 생성했던 Notify 이름 검색 으로 Notify 설정을 할 수 있다.
    • 4번에서 만든 DoAttackCombo() 메소드를 연결할 것인데, Notify 에서 바로 연결을 할 수 없다.
      가져오기 위해선 Context Sensitive를 비활성화 시켜 검색을 통해 가져올 수 있다.
    • 아래와 같이 구현했다. (자세히 설명하기가 어려워 아래 이미지를 추가했다 ㅠㅠ)

우측 설명이 잘 안보여서 아래에 작성했다

1
2
3
4
5
6
7
8
DoAttackCombo() 에서
Montage_Stop(1.f,CombatMeleeAnimMontage);를 했는데

1.f로 인해 블랜딩 도중 bAttacking이 false가 되버린다.
(이럴 경우, 블랜딩 도중 공격 중이 아님이 되버리기에 여러 문제가 발생할 수 있다. (EX. 블랜딩 도중 캐릭터가 움직여짐))

이를 방지하기 위해
Delay를 1초 주어 블랜딩이 끝난 후 bAttacking = false 가 되게 설정하였다.

4. 결과

This post is licensed under CC BY 4.0 by the author.