본문 바로가기
Unreal/Manual

Unreal C++ AnimNotifyState 사용 하기

by Dev_카페인 2023. 11. 30.
반응형

[Unreal/C++] AnimNotifyState 사용 하기

Anim Notify State (애님 노티파이 스테이트), 또는 Notify State (노티파이 스테이트)는 위의 표준 노티파이와 비슷합니다. 다른 점은 begin(시작), tick(틱), end(끝) 세 개의 이벤트가 있습니다. 단순히 시작해서 노티파이 시작과 끝 지점에 발동되고, 애니메이션에서 시간이 다가왔을 때 그 안의 이벤트 그래프 가 발동됩니다. 틱은 끝 이벤트에 도달할 때까지 모든 애니메이션 업데이트를 발동합니다. 보통 노티파이와 노티파이 스테이트와 큰 차이점은, 자체 독립적인 블루프린트 라는 점입니다.

 

애니메이션 노티파이 스테이트를 사용해 보겠습니다.

AnimNotifyState를 상속받은 C++ 클래스를 생성합니다.

 

C++ 클래스 생성시 아래와 같은 코드가 작성됩니다.

#pragma once

#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotifyState.h"
#include "ANS_DoubleShot.generated.h"

UCLASS()
class MAINPROJECT_API UANS_DoubleShot : public UAnimNotifyState
{
	GENERATED_BODY()
};

애니메이션 몽타주에서 NotifyState를 추가하기 위해서 UAnimNotifyState에 정의되어 있는 함수를 오버라이드 해야합니다.

UAnimNotifyState클래스로 이동하여 헤더 코드를 잠깐 살펴보면 아래와 같은 함수를 볼 수 있습니다.

언리얼 엔진 5.0부터?는 상단에 있는 Notify함수(Begin, Tick, End)를 사용하지 않고 아래쪽 함수를 이용하라고 합니다.

변경 전 API를 사용하려 하면 친절하게도 업데이트 안내를 받을 수 있습니다.

Please update your code to the new API before upgrading to the next release, otherwise your project will no longer compile.
다음 릴리스로 업그레이드하기 전에 코드를 새 API로 업데이트하세요. 그렇지 않으면 프로젝트가 더 이상 컴파일되지 않습니다.

UAnimNotifyState C++ 파일을 확인해보니 기존의 Notify함수는 비어있고 아래쪽에서 경고를 일으킨다는 함수가 보입니다.

Blueprint에서는 Received_Notify함수를 사용하는 것 같습니다.

우리가 사용하게 될 아래 함수를 복사하여 헤더파일에 선언해주고 override합니다.

virtual void NotifyBegin(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference);
virtual void NotifyTick(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, float FrameDeltaTime, const FAnimNotifyEventReference& EventReference);
virtual void NotifyEnd(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, const FAnimNotifyEventReference& EventReference);
#pragma once

#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotifyState.h"
#include "ANS_DoubleShot.generated.h"

UCLASS()
class MAINPROJECT_API UANS_DoubleShot : public UAnimNotifyState
{
	GENERATED_BODY()
    
    virtual void NotifyBegin(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
	virtual void NotifyTick(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, float FrameDeltaTime, const FAnimNotifyEventReference& EventReference) override;
	virtual void NotifyEnd(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, const FAnimNotifyEventReference& EventReference) override;
    
};

 

3개의 Notify 함수를 구현합니다.

구현 시 부모의 Notify 함수를 호출해주고 사용할 오브젝트나 클래스를 받아 원하는 기능을 구현합니다.

이 때 조심할점은 에디터에서 게임이 시작되기 전에는 오브젝트나 클래스가 할당되지 않은 상태가 많기 때문에 예외처리를 꼼꼼히 해주셔야 합니다.

여기서 Tick은 사용하지 않았습니다.

#include "Character/Notifies/AN_DoubleShot.h"
#include "Character/Character_TwinBlast.h"

void UANS_DoubleShot::NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference)
{
	Super::NotifyBegin(MeshComp, Animation, TotalDuration);

	// 구현 내용
	if (Target == nullptr) return;
	Target->Function();
}

void UANS_DoubleShot::NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference)
{
	Super::NotifyEnd(MeshComp, Animation);

	// 구현 내용
	if (Target == nullptr) return;
	Target->Function();
}

 

위 처럼 구현을 마친 코드는 컴파일 후 애니메이션 몽타주에 애니메이션 노티파이 스테이트를 추가할 수 있습니다.

추가하기 전에 애니메이션 몽타주를 일시정지 하지 않으면 설정과 동시에 Fatal Error를 마주할 확률이 있으므로 신중해야 합니다.

 

반응형