Unreal/언리얼 엔진 4 입문

[언리얼 입문]스탯 매니저

잡템 2023. 11. 1. 00:16

데이터 테이블을 대략적으로 어떤식으로 불러서 사용하는지 실습해보았다.

 

//게임 인스턴스 헤더
USTRUCT()
struct FMyCharacterData : public FTableRowBase
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 Level;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 Attack;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 MaxHp;
};

먼저 게임 인스턴스를 생성한뒤 데이터 테이블로 사용할 캐릭터정보를 구조체로 선언해주고

프로젝트 세팅- 맵&모드탭에서 게임 인스턴스 클래스 항목을 새로 만든 게임 인스턴스로 교체해준다.

//게임 인스턴스 CPP
UMyGameInstance::UMyGameInstance()
{
    static ConstructorHelpers::FObjectFinder<UDataTable> DATA(TEXT("데이터 테이블 경로"));

    if(DATA.Succeeded())
    {
        MyStats = DATA.Object;
    }
}

FMyCharacterData* UMyGameInstance::GetStatData(int32 Level)
{
    return MyStats->FindRow<FMyCharacterData>(*FString::FromInt(Level), TEXT(""));
}

데이터 테이블을 불러오고 해당 데이터 테이블에서 레벨에 맞는 스탯정보를 받아올수 있게 함수를 만들어둔다.

 

//스탯 컴포넌트 CPP
void UMyStatComponent::InitializeComponent()
{
	Super::InitializeComponent();

	SetLevel(Level);
}

void UMyStatComponent::SetLevel(int32 NewLevel)
{
	auto MyGameInstance = Cast<UMyGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()));
	if(MyGameInstance)
	{
		auto StatData = MyGameInstance->GetStatData(NewLevel);
		if(StatData)
		{
			Level = StatData->Level;
			Hp = StatData->MaxHp;
			Attack = StatData->Attack;
		}
	}
}

void UMyStatComponent::OnAttacked(float DamageAmount)
{
	Hp -= DamageAmount;
	if(Hp < 0)
		Hp = 0;

	UE_LOG(LogTemp, Warning, TEXT("OnAttacked %d"),Hp);
}

캐릭터 등에 스탯을 부여하기위에 ActorComponet를 베이스로 StatComponent를 생성

GetGameInstance는 싱글톤처럼 어디서든 게임 인스턴스에 접근하기위한 함수라고 한다.

//캐릭터 CPP
void AMyCharacter::AttackCheck()
{
	if(isCollision && HitResult.Actor.IsValid())
	{
		UE_LOG(LogTemp,Log,TEXT("Hit Actor : %s"), *HitResult.Actor->GetName());
		FDamageEvent DamageEvent;
		HitResult.Actor->TakeDamage(Stat->GetAttack(),DamageEvent,GetController(),this);
	}
}

float AMyCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
	Stat-> OnAttacked(DamageAmount);

	return DamageAmount;
}

캐릭터쪽에서 스탯을 정보를 활용하기위해 이전 충돌처리 로직을 활용하여 맞은 상대쪽에서 TakeDamage에 지금 캐릭터의 공격력을 전달하도록 하게 한다.

 

TakeDamage는 액터에 기본적으로 있는 함수라고 하며 이걸 오버라이딩해서 캐릭터가 타격받으면 OnAttacked를 호출해

Hp를 갱신하도록 처리한다.

 

현재는 따로 몬스터같은게 없어서 실습에서는 이전에 공격판정을 테스트하기위해 플레이어 조작캐릭터 말고도 별도로 캐릭터를 하나 배치해뒀었는데 이번에도 그대로 활용하게되었다.

정삭적으로 동작하게되면 이런식으로 캐릭터가 피격시 받은 데미지만큼 Hp를 감소시키고 로그를 출력한다.