본문 바로가기

게임프로그래밍/실습1

[언리얼 실습] 79. 픽업 인터페이스 & 소울 픽업 효과


목차

  1. 픽업 인터페이스 구현
  2. 소울 획득시 효과 주기

1. 픽업 인터페이스 구현

 

소울을 획득하는 기능을 구현할 것이다. 소울뿐만 아니라 골드도 획득할 수 있어야 하며 인터페이스를 만들어 이를 구현할 것이다.

 

인터페이스를 만들자.

 

class PRACTICE_API IPickupInterface
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
	virtual void SetOverlappingItem(class AItem* Item) = 0;

};

 

순수가상함수를 만들었다.

 

아이템 클래스에는 OnSphereOverlap() 함수가 있고 이곳에서 오버랩된 액터를 캐릭터로 캐스트해 플레이어인지 아닌지 알고 이후의 작업을 진행한다. 이제 캐릭터로 캐스트하는 것이 아니라 픽업 인터페이스로 캐스트하여 이 작업들을 할 것이다.

 

캐릭터 클래스에 인라인 함수로 SetOverappingItem() 함수가 있는데 이제 인터페이스에서 이 함수를 사용하기 때문에 인라인 함수를 지우고 오버라이드하여 사용하도록 하자.

 

#include "Interface/PickupInterface.h"
#include "Knight.generated.h"

UCLASS()
class PRACTICE_API AKnight : public ABaseCharacter, public IPickupInterface
{
GENERATED_BODY()

public:
	virtual void SetOverlappingItem(class AItem* Item) override;

 

이렇게 상속을 받고 오버라이드 까지 하였다.  이제 이것을 정의해야 한다.

 

void AKnight::SetOverlappingItem(AItem* Item)
{
	OverlappingItem = Item;
}

 

그러면 이제 아래 함수를 바꿀 수 있다.

 

#include "Knight.h"

void AItem::OnSphereOverlap(매개변수 생략)
{
	AKnight* KnightCharacter = Cast<AKnight>(OtherActor);
	if (KnightCharacter)
	{
		KnightCharacter->SetOverappingItem(this);
	}
}

 

위의 함수에서 아래의 함수로 바꾼다.

#include "Interface/PickupInterface.h"

void AItem::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	IPickupInterface* PickupInterface = Cast<IPickupInterface>(OtherActor);
	if (PickupInterface)
	{
		PickupInterface->SetOverlappingItem(this);
	}
}

 

이제 이렇게 바꾸면 꼭 캐릭터 클래스가 아니라 인터페이스를 상속받은 클래스는 전부 이 기능을 쓸 수 있을 것이다.

 

이제 소울을 획득하는 함수를 만들자.

 

// 픽업인터페이스.h

virtual void AddSouls(class ASoul* Soul) = 0;

 

 

 

캐릭터 클래스에서 오버라이드 한 뒤 실제 구현전 테스트를 먼저 해보려고 한다.

 

void AKnight::AddSouls(ASoul* Soul)
{
	UE_LOG(LogTemp, Warning, TEXT("AddSouls"));
}

 

 

이제 소울 클래스에서 이것을 사용하면 된다.

 

void ASoul::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	IPickupInterface* PickupInterface = Cast<IPickupInterface>(OtherActor);
	if (PickupInterface)
	{
		PickupInterface->AddSouls(this);
	}
    Destroy();
}

 

컴파일하고 작동하는지 확인하자.

 


2. 소울 픽업 효과

 

소울을 실제로 획득하는 부분을 구현해야하지만 그전에 간단하게 소울 획득시 획득 효과를 주려고 한다.

 

UCLASS()
class PRACTICE_API ASoul : public AItem
{
	GENERATED_BODY()
	
private:
	UPROPERTY(EditAnywhere)
	class UNiagaraSystem* PickupEffect;
};

 

효과를 담을 변수를 추가하자.

 

오버랩 함수에 픽업 이펙트를 스폰하는 구문을 추가하자.

 

#include "NiagaraFunctionLibrary.h"


void ASoul::OnSphereOverlap(매개변수 생략)
{
	IPickupInterface* PickupInterface = Cast<IPickupInterface>(OtherActor);
	if (PickupInterface)
	{
		PickupInterface->AddSouls(this);
	}

	if (PickupEffect)
	{
		UNiagaraFunctionLibrary::SpawnSystemAtLocation(
			this,
			PickupEffect,
			GetActorLocation()
		);
	}

	Destroy();
}

 

소울을 획득하면 사운드도 출력하게 해보자.

 

UPROPERTY(EditAnywhere)
USoundBase* PickupSound;
if (PickupSound)
{
	UGameplayStatics::SpawnSoundAtLocation(
		this,
		PickupSound,
		GetActorLocation()
	);
}

 

기본적인 기능을 만들었으니 다음에는 실제로 소울을 획득하면 소울이 증가하게 만들 것이다.