KoreanFoodie's Study

[언리얼] 언리얼 인터페이스 - Does Implement Interface 기능으로 데미지, 인터랙션 구현하기 본문

Game Dev/Unreal C++ : Dev Log

[언리얼] 언리얼 인터페이스 - Does Implement Interface 기능으로 데미지, 인터랙션 구현하기

GoldGiver 2022. 6. 22. 09:48

Does Implement Interface 기능으로 데미지, 인터랙션 구현하기

총을 쏘았을때, 맞은 대상이 Enemy 이면 데미지를 전달하고 싶거나, 만약 상호작용 가능한 오브젝트인 경우 상호작용을 하고 싶다고 가정하자. 해당 기능을 어떻게 구현하면 좋을까?

물체의 경우, 각 물체에 트리거를 심는 경우도 생각해 볼 수 있겠지만, 배치되는 모든 오브젝트마다 트리거를 따로 설정해야 된다고 생각하면 너무 끔찍할 것이다.

데미지의 경우, 총에 맞은 액터가 데미지를 받을 수 있는지 없는지를 어떻게 판별하면 좋을까? 사실 Enemy 말고도 부술 수 있는 오브젝트도 마찬가지로 데미지를 받아야 할텐데, 각 클래스마다 데미지를 받는지 안 받는지를 설정하는 것은 매우 귀찮은 일이다.

 

언리얼에서는 Does Implement Interface 기능을 적극 활용하여, 내가 원하는 동작을 할지 말지를 쉽게 판별할 수 있다.

위는 블루프린트에서 사용하는 Does Implement Interface 이다. 블루프린트 이벤트 그래프에서 Interface 를 추가하고, Does Implement Interface 로 체크하면 된다

예를 들어, BulletHit 라는 인터페이스를 만들었다고 가정하자. (인터페이스 앞에는 I 를 붙이는게 규약이다) 그럼 해당 인터페이스를 상속한 (C++ 는 다중 상속을 지원한다) 클래스는 데미지를 받을 수 있으며, 데미지를 주는 클래스 (일반적으로 Player 캐릭터) 에서 총알과 충돌한 오브젝트의 GetDamage 함수를 호출하는 식으로 데미지 기능을 구현할 수 있을 것이다.

 

언리얼 인터페이스는 다음과 같이 만들 수 있다. (언리얼 C++ 기준)

먼저, C++ 클래스를 생성한다. 이때 부모 클래스는 Unreal Interface 로 설정한다.

 

그리고 다음과 같은 형식으로  우리가 원하는 함수를 생성한다.

BulletHitInterface.h

UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void BulletHit(FHitResult HitResult);

BlueprintNativeEvent 는 UFUNCTION 의 3 가지 프로퍼티 중 하나인데, 간략하게 정리하면 다음과 같다 :

  • BlueprintCallable : C++ 로 작성됨. 블루프린트 그래프에서 호출 가능하지만 변경이나 덮어쓰기는 불가능 (e.g. 수학 함수)
  • BlueprintImplementableEvent : 헤더 파일 (.h) 에 추가되지만, 함수 본문은 C++ 가 아닌 블루프린트 그래프에서 작성됨. 표준 동작이 없는 이벤트를 자유롭게 변경할 수 있도록 하는 경우에 사용. (e.g. 각 보스마다 다른 보상을 줌)
  • BlueprintNativeEvent : BlueprintCallable 과 BlueprintImplementableEvent 의 조합형. C++ 로 작성되었지만, 블루프린트에서 보조 또는 대체 가능함. BlueprintNativeEvent 를 사용할 때는 함수 마지막에 "_Implementation" 을 붙여야 함.

 

이제 인터페이스를 상속하고, 함수를 오버라이딩하자.

Enemy.h

...
#include "BulletInterface.h"
#include "Enemy.generated.h"

UCLASS()
class SHOOTER_API AEnemy : public ACharacter, public IBulletHitInterface

...

public:
    virtual void BulletHit_Implementation(FHitResult HitResult) override;

 

Enemy.cpp

void AEnemy::BulletHit_Implementation(FHitResult HitResult)
{
	...
}

그리고 우리가 원하는 동작을 넣어주면 된다!

 
Comments