본문 바로가기

게임프로그래밍/실습1

[언리얼 실습] 80. 소울과 골드에 실제 속성 더하기


목차

  1. 소울과 골드 습득시 캐릭터 속성에 추가
  2. 에너미가 소울을 드랍하게 하기

1. 소울과 골드 습득시 캐릭터 속성에 추가

 

캐릭터의 속성은 Attribute 클래스에서 담당하고 있고 이곳에 골드와 소울의 양을 저장할 변수를 만들 것이다.

 

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class PRACTICE_API UAttributeComponent : public UActorComponent
{
	GENERATED_BODY()

public:	
	UAttributeComponent();
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

protected:
	virtual void BeginPlay() override;

private:
	// 현재 체력
	UPROPERTY(EditAnywhere, Category = "Actor Attribute")
	float Health = 100;

	UPROPERTY(EditAnywhere, Category = "Actor Attribute")
	float MaxHealth = 100;

	UPROPERTY(VisibleAnywhere, Category = "Actor Attribute")
	int32 Gold;

	UPROPERTY(VisibleAnywhere, Category = "Actor Attribute")
	int32 Souls;

public:
	void ReceiveDamage(float Damage);
	float GetHealthPercent();
	bool IsAlive();
	void AddSouls(int32 NumberOfSouls);
	void AddGold(int32 AmountOfGold);

	FORCEINLINE int32 GetGold() const { return Gold; }
	FORCEINLINE int32 GetSouls() const { return Souls; }
	
		
};

 

이제 소울과 골드를 추가해주는 함수를 정의하자.

 

void UAttributeComponent::AddSouls(int32 NumberOfSouls)
{
	Souls += NumberOfSouls;
}

void UAttributeComponent::AddGold(int32 AmountOfGold)
{
	Gold += AmountOfGold;
}

 

캐릭터 클래스에서는 이미 AddSouls 함수가 존재한다. 이곳에서 어트리뷰트의 함수를 호출해서 값을 넣어주면 될 것이다.

 

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

 

위와 같은 함수가 있는데 여기서 소울의 양을 알아야하고 그러한 변수는 소울 클래스에 만들어주어야 할 것이다.

 

class PRACTICE_API ASoul : public AItem
{
	GENERATED_BODY()
	
protected:
	virtual void OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override;

private:
	UPROPERTY(EditAnywhere)
	int32 Souls;

public:
	FORCEINLINE int32 GetSouls() const { return Souls; }
};

 

이제 다시 캐릭터 클래스로 가 값을 더해주면 될 것이다.

 

void AKnight::AddSouls(ASoul* Soul)
{
	if (Attributes && Soul)
	{
		Attributes->AddSouls(Soul->GetSouls());
	}
}

 

값을 바꾸었으니 HUD도 업데이트 해주어야 한다.

 

void AKnight::AddSouls(ASoul* Soul)
{
	if (Attributes && Soul && SlashOverlay)
	{
		Attributes->AddSouls(Soul->GetSouls());
		SlashOverlay->SetSouls(Attributes->GetSouls());
	}
}

 

어트리뷰트는 실제 소울의 양이 저장되는 변수를 가져오고 더한다.

슬래시 오버레이는 위젯에서 보여줄 텍스트를 설정하는 역할을 한다.

 


2. 에너미가 소울을 드랍하게 하기

 

에너미가 소울을 드랍할때는 유의해야할 점이 있다. 골드의 경우 보물 마다 값이 정해져있어 그 값을 가져와 더해주면 되지만 소울의 경우 모든 소울 클래스가 동일하지만 값은 다르게 설정 될 것이다.

 

그러면 에너미가 소울을 드랍할때 이 소울의 양도 설정할 수 있어야 할 것이다.

 

에너미 클래스로 들어가자. 에너미가 소울을 스폰할 것이기 때문에 이 소울을 담을 변수가 필요하다.

UPROPERTY(EditAnywhere)
TSubclassOf<class ASoul> SoulClass;

 

이제 이 소울을 스폰하자. 스폰은 에너미가 죽으면 할 것이다.

 

#include "Items/Soul.h"

UWorld* World = GetWorld();
if (World && SoulClass)
{
	World->SpawnActor<ASoul>(SoulClass, GetActorLocation(), GetActorRotation());
}

 

이제 이 스폰된 소울의 값을 설정해주어야 한다. 이 스폰 액터 함수가 소환된 액터를 반환해준다. 이 값을 저장하자.

 

다만 그러려면 소울 클래스에 세터가 있어야 할 것이다. 만들어주고 오면 된다.

 

void AEnemy::SpawnSoul()
{
	UWorld* World = GetWorld();
	if (World && SoulClass && Attributes)
	{
		ASoul* SpawnedSoul = World->SpawnActor<ASoul>(SoulClass, GetActorLocation(), GetActorRotation());
		if (SpawnedSoul)
		{
			SpawnedSoul->SetSouls(Attributes->GetSouls());
		}
	}
}

 

소울의 값은 에너미 클래스가 아닌 어트리뷰트 클래스에 있기 때문에 거기서 값을 가져와주면 된다.

 

에너미 블루프린트 클래스에서 소울 클래스를 설정하는 것을 잊지 말자.

 

 

 

소울이 스폰되자마자 바로 먹어지는 문제가 있기는 하지만 어쨌든 소환이 잘 되는 것을 볼 수 있다.