본문 바로가기

게임프로그래밍/실습1

[언리얼 실습] 16. 애니메이션 몽타주로 공격 모션 만들기


목차

  1.  공격 몽타주 만들기
  2. 인풋 액션 만들기
  3. C++ 에서 몽타주 재생하기

1. 공격 몽타주 만들기

 

애니메이션 몽타주를 이용하여 공격 모션을 만들어보려고한다.

 

 

콘텐츠 브라우저에서 애니메이션 몽타주를 만들자. 애니메이션 몽타주를 누르면 매시를 선택하라고 뜨는데 우리가 쓰고 있는 캐릭터의 매시를 고르면 된다.

 

몽타주 안으로 들어가자

 

 

 

우측 하단에 있는 애셋 브라우저에서 해당 스켈레톤에서 사용할 수 있는 애니메이션들을 볼 수 있는데 이곳에서 공격 애니메이션을 가져다가 디폴트 그룹으로 가져가면 된다.

 

 

이제 이곳에서 섹션을 나눌 것이다 가장 상단바에서 우클릭을 하면 새 섹션을 만들 수 있다.

 

 

다음과 같이  섹션을 나누자. 현재 섹션은 나누어져 있지만 애니메이션은 연속적으로 이어진다. 그렇기 때문에 이를 분리할 필요가 있다.

 

 

우측 몽타주 섹션에서 클리어를 누르면 된다.

 

이제 이 몽타주를 애니메이션 블루프린트에서 재생해야 하는데  이때 슬롯 이름을 알아야 한다. 따로 지정을 하지 않으면 디폴트 슬롯으로 생성된다.

 

이제 캐릭터 애니메이션으로 돌아가자.

 

 

슬롯을 검색하면 (이름을 따로 지정하지 않았기 때문에)디폴트 슬롯이 보인다.

 

 

슬롯의 역할은  해당 슬롯 그룹에 속해있는 몽타주를 재생하면 슬롯으로 들어오기 전의 애니메이션 (여기서는 메인스테이트의 애니메이션)을 덮어쓰고 몽타주의 애니메이션을 재생시켜주는 역할이라고 한다.

 

그럼 이제 몽타주를 재생 시키면 된다.

 

몽타주는 C++에서 재생할 것이다. 그전에 공격을 하기위한 설정을 하자.


 

2. 인풋 액션 만들기

 

 

 

입력을 바인딩하기 위해 인풋액션을 만들자. 현재 실습에서는 콤보 공격을 만들지 않을 것이기 때문에 따로 설정은 하지 않아도 된다.

 

컨텍스트에 매핑을 한뒤 이제 비주얼스튜디오로 가서 몽타주를 재생해보려고 한다.


3. C++ 에서 몽타주 재생하기

 

캐릭터 헤더파일로 들어가 공격 액션에 바인딩할 함수와 인풋 액션을 만들고 몽타주를 담을 변수를 선언하자.

 

protected:
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	UInputAction* AttackAction;

    void Attack();
    
 private:
 	UPROPERTY(EditDefaultsOnly, Category = "Montage")
	UAnimMontage* AttackMontage;

 

cpp 파일로 들어가 바인딩을 해준다.

 

EnhancedInputComponent->BindAction(
	AttackAction,
    ETriggerEvent::Started,
    this,
    &AKnight::Attack
   	);

 

이제 attack 함수를 정의해보자.

 

void AKnight::Attack()
{
	UAnimInstance* AnimInstace = GetMesh()->GetAnimInstance();
	if (AnimInstace && AttackMontage)
	{
		AnimInstace->Montage_Play(AttackMontage);
	}
}

 

로컬변수로 애님인스턴스를 설정하고 애님인스턴스와 공격 몽타주가 nullptr이 아닌지 확인한 후 애님인스턴스에 있는 함수 Montage_Play로 몽타주를 재생해준다.

 

현재 우리가 몽타주에 가지고 있는 애니메이션은 2개가 있는데 이를 랜덤으로 재생할 것이다.

 

랜덤재생의 기본원리는 몽타주에 속해있는 0에서 부터 애니메이션의 수 사이의 랜덤 숫자를 뽑아 숫자에 해당하는 애니메이션을 재생하면 되는데 이때 숫자를 하드코딩을 하게 되면 나중에 애니메이션이 추가되거나 삭제될때 일일이 수정하는 귀찮은 작업이 발생할 것이다.

 

그렇기 때문에 섹션의 이름과 숫자를 함수를 이용해서 가져올 것이다.

 

void AKnight::Attack()
{
	UAnimInstance* AnimInstace = GetMesh()->GetAnimInstance();
	if (AnimInstace && AttackMontage)
	{
		AnimInstace->Montage_Play(AttackMontage);
		
        // 해당 몽타주의 섹션 숫자를 가져오고 거기서 1을 뺀다
		const int32 SectionCount = AttackMontage->GetNumSections() - 1;
        // 0에서 부터 섹션의 숫자 -1 의 값 중 랜덤값을 가져온다.
		int32 Selection = FMath::RandRange(0, SectionCount);
        // 인덱스를 이용해서 섹션의 이름을 가져온다.
		const FName SectionName = AttackMontage->GetSectionName(Selection);
        // 해당 섹션으로 점프한다.
		AnimInstace->Montage_JumpToSection(SectionName, AttackMontage);

	}
}

 

이제 컴파일을 하고 잘 되는 지 확인하자. 그전에 설정들을 해야한다.

 

 

인풋 액션과 몽타주를 설정하자.

 

 

애니메이션들이 잘 재생되는 것을 볼 수 있다.

 

현재까지 구현한 것은 문제가 많다. 공격중에 이동도 가능하고 계속해서 버튼을 누르면 애니메이션이 반복 재생된다.

 

다음에는 이 부분을 고쳐보자