게임 구현하면서 서로 다른 클래스끼리 통신을 할때 각 클래스에 Interface클래스를 상속시켜서 쉽게 통신을 할 수 있습니다.

 

해당 게시글에서는 Interface + Notify를 이용하여 장전하는 애니메이션에서 장전되는 순간 함수가 호출되는 기능을 만들어 보겠습니다.

 

 

1. TPS 샘플 프로젝트에 장전하는 애니메이션 기능 추가

 


ACharacther.h

#include "EngineMinimal.h"

#include "GameFramework/Character.h"

#include "TestCharacter.generated.h"



UCLASS(config=Game)

class ATestCharacter : public ACharacter

{

 GENERATED_BODY()

...

...

...



private :

   //! 애니메이션 시퀸스 변수

 UPROPERTY(EditDefaultsOnly, Category = Animation, Meta = (AllowPrivateAccess = true))

 class UAnimSequenceBase* m_pAnimSequence_Reload;

 


ACharacter.cpp

ACharacter::ACharacter()
{
...

...

...

 

static ConstructorHelpers::FObjectFinder<UAnimSequenceBase> Asset_AnimMtg(TEXT("AnimSequence'/Game/Reload_Rifle_Ironsights.Reload_Rifle_Ironsights'")); //! 경로 입력
if (Asset_AnimMtg.Succeeded())
{
 m_pAnimSequence_Reload = Asset_AnimMtg.Object;         //! 시퀸스 변수 세팅
}
...
...
...
}

//! 키바인딩 함수 -> 애니메이션을 Default Slot에 재생
void ACharacter::Action_Reload()
{
 UAnimMontage* pAnimationMtg = GetMesh()->GetAnimInstance()->PlaySlotAnimationAsDynamicMontage(m_pAnimSequence_Reload,         TEXT("DefaultSlot"), 0.3f, 0.3f, 1.0f);
 PlayAnimMontage(pAnimationMtg, 1.0f);
}
 

 

 

 

애니메이션 블루프린트의 Anim Grap에 Default Slot 노드 추가합니다, Slot을 이용해서 Full Body 애니메이션을 돌릴 예정입니다.

 

 

장전 애니메이션 재생기능 세팅 완료

 

 

 

2. Interface Class 제작

 

 

Itf_AnimationNotify.h


#include "CoreMinimal.h"

#include "UObject/Interface.h"

#include "Itf_AnimationNotify.generated.h"



// This class does not need to be modified.

UINTERFACE(MinimalAPI)

class UItf_AnimationNotify : public UInterface

{

 GENERATED_BODY()

};



/**

 * 

 */

class TEST_API IItf_AnimationNotify

{

 GENERATED_BODY()

public:

 //! 사용할 Interface 함수 코드 추가 (여러 개 가능)

 UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Itf_Reload")  //! Blueprint상에서 사용할 수 있도록 UFunction세팅 

 void Itf_ReloadDone(int nTestValue);

};

 

Itf_AnimationNotify.cpp 파일은 따로 수정하지 않습니다,

 

 


ACharacter.h

#include "Itf_AnimationNotify.h"    //! Interface클래스 Include



#include "EngineMinimal.h"

#include "GameFramework/Character.h"

#include "TestCharacter.generated.h"



UCLASS(config=Game)

class ATestCharacter : public ACharacter, public IItf_AnimationNotify    //! Interface 클래스 상속

{

 GENERATED_BODY()

...

...

...

public :

//! 실제 구현 부 함수 정의

 UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Itf_Reload")

 void Itf_ReloadDone(int nTestValue);

 virtual void Itf_ReloadDone_Implementation(int nTestValue) override;



...

...

...

}


 


ACharacter.cpp

...

...

//! Interface함수 호출시 호출될 함수 선언

void ACharacter::Itf_ReloadDone_Implementation(int nTestValue)

{

 UE_LOG(LogTemp, Warning, TEXT("Reload Done_%d"), nTestValue);

}



...

...

 

정의부분에서는 "Implementation"가 붙은 함수와 붙지 않은 함수 2개를 만들었지만 cpp선언에서는 "Implementation"가 붙은 함수만 작성합니다.

이것으로 Interface함수 세팅은 완료입니다.

 


인터페이스 함수 호출하는 법

ACharacter* pCharacter = FindActor("Charactor");        //! 해당 클래스 포인터 가져오기

if (ACharacter->GetClass()->ImplementsInterface(UItf_AnimationNotify::StaticClass()) == true) //! 해당 클래스에 해당 Interface클래스가 존재하는지 확인

{

 IItf_AnimationNotify::Execute_Itf_ReloadDone(pCharacter, 123456);        //! 함수 호출, 

//! 1번 인자 : 호출할 클래스

//! 2번 인자 뒤 : 정의한 함수 인자

}

다른 클래스에서 호출할때는 정의한 함수 명 앞에 "Execute_"를 붙여야 합니다.

 


 

2. Anim Notify 제작 후 Interface 연동

 

Anim Notify Blueprint 클래스를 제작합니다.

 

Override함수를 생성하여 위 사진과 같이 Interface함수를 호출하는 노드를 제작합니다.

 

 

장전 애니메이션에서 장전이 완료되는 부분에 Notify 추가하고 우측 디테일 패널에서 인자값을 넣을 수 있습니다.

 

 

로그로 테스트 결과 성공적으로 Notify + Interface가 동작되는 것을 확인 했습니다.

 

 

 

 

참고자료 

 

https://wiki.unrealengine.com/Interfaces_in_C%2B%2B

 


WRITTEN BY
CatDarkGame
Technical Artist dhwlgn12@gmail.com

,