KannaTPSOverlay의 탄약 개수가 실제로 업데이트되도록 할 것이다.
우선, KannaTPSOverlay 클래스 안에 탄약 개수를 설정하는 함수를 만들어주었다.
void UKannaTPSOverlay::SetCurrentAmmoText(int32 Amount)
{
if (CurrentAmmoText)
{
FString String = FString::FromInt(Amount);
CurrentAmmoText->SetText(FText::FromString(String));
}
}
void UKannaTPSOverlay::SetTotalAmmoText(int32 Amount)
{
if (TotalAmmoText)
{
FString String = FString::FromInt(Amount);
TotalAmmoText->SetText(FText::FromString(String));
}
}
인자로 int타입 숫자를 받아, FText로 변환하여 UI를 바꾼다.
그리고, 무기를 장착하고있지 않다면 굳이 탄약 개수 UI를 띄워줄 필요가 없을 것이다.
따라서 탄약 UI를 숨기고 보여주는 함수도 만들었다.
void UKannaTPSOverlay::HideAmmoText()
{
CurrentAmmoText->SetVisibility(ESlateVisibility::Hidden);
TotalAmmoText->SetVisibility(ESlateVisibility::Hidden);
AmmoTextSlash->SetVisibility(ESlateVisibility::Hidden);
}
void UKannaTPSOverlay::ShowAmmoText()
{
CurrentAmmoText->SetVisibility(ESlateVisibility::Visible);
TotalAmmoText->SetVisibility(ESlateVisibility::Visible);
AmmoTextSlash->SetVisibility(ESlateVisibility::Visible);
}
이제 이 함수들을 호출하여 UI를 업데이트 할 것이다.
업데이트 할 상황은 다음과 같다.
- 총을 쏠 때 현재 탄약 개수 줄이기
- 재장전할 때 현재 탄약 개수 늘리기, 전체 탄약 개수 줄이기
- 총을 꺼낼 때 UI 보여주기, 집어넣을 때 UI 숨기기
총을 쏘고 재장전하는 것은 Gun의 역할이므로, Gun에서 KannaTPSOverlay를 참조할 수 있어야 한다.
HUD는 KannaCharacter가 사용하고 있는 것이라고 할 수 있다. 따라서 Gun에서 KannaCharacter를 통해, Overlay를 참조할 수 있게 하려고 한다.
Gun에서 KannaCharacter를 사용할 수 있도록, 변수를 하나 만들고 GetPlayerPawn을 통해 할당해주었다.
// Called when the game starts or when spawned
void AGun::BeginPlay()
{
Super::BeginPlay();
KannaCharacter = Cast<AKannaCharacter>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
}
그렇다면 KannaCharacter에서는 KannaTPSOverlay를 넘겨줄 준비를 하고있어야 한다.
KannaCharacter에서도 KannaTPSOverlay 포인터 변수를 하나 만들고, 다음과 같이 할당해놓는다.
//BeginPlay에서 호출됨
void AKannaCharacter::InitKannaTpsOverlay()
{
if (APlayerController* PlayerController = Cast<APlayerController>(GetController()))
{
AKannaTPSHUD* KannaTPSHUD = Cast<AKannaTPSHUD>(PlayerController->GetHUD());
if (KannaTPSHUD)
{
KannaTPSOverlay = KannaTPSHUD->GetKannaTPSOverlay();
if (KannaTPSOverlay)
{
KannaTPSOverlay->HideAmmoText(); //탄약 개수는 숨기는게 기본값
}
}
}
}
플레이어 컨트롤러를 가져와 GetHUD로 KannaTPSHUD를 뽑아내고, 그 안에서 다시 KannaTPSOverlay 를 뽑아내어 변수에 저장해준다.
KannaTPSOverlay 포인터는 private 섹션에 있다. 넘겨주기 위한 간단한 public getter를 만들어주었다.
FORCEINLINE UKannaTPSOverlay* GetKannaTPSOverlay() {return KannaTPSOverlay;}
이제 Gun에서 KannaCharacter->GetKannaTPSOverlay()를 통하여 오버레이를 사용할 수 있다.
우선 Gun.cpp의 Fire 함수 맨 마지막에서 SetCurrentAmmoText를 호출하여 업데이트하도록 했다.
void AGun::Fire(FVector& StartPoint, FVector& Direction)
{
CurrentAmmo = FMath::Clamp(CurrentAmmo-1, 0, MaxAmmo);
KannaCharacter->GetKannaTPSOverlay()->SetCurrentAmmoText(CurrentAmmo);
}
Reload에서도 다음과 같이 UI를 업데이트한다.
void AGun::Reload()
{
if (MaxAmmo == CurrentAmmo)
return;
UE_LOG(LogTemp,Warning, TEXT("RELOAD"));
int32 ReloadingAmmo = MaxAmmo - CurrentAmmo;
TotalAmmo -= ReloadingAmmo;
CurrentAmmo = MaxAmmo;
KannaCharacter->GetKannaTPSOverlay()->SetCurrentAmmoText(CurrentAmmo);
KannaCharacter->GetKannaTPSOverlay()->SetTotalAmmoText(TotalAmmo);
}
KannaCharacter에서는 무기를 넣고 뺌에 따라 UI를 보여주고 숨길 수 있도록, SwitchWeapon 함수를 다음과 같이 수정하였다.
void AKannaCharacter::SwitchWeapon()
{
if(ActionState != EActionState::EAS_Neutral) return;
if (CharacterState == ECharacterState::ECS_ArmedWithPistol) // 권총 -> 맨손
{
CharacterState = ECharacterState::ECS_Unarmed;
CurrentWeapon = nullptr;
}
else if (CharacterState == ECharacterState::ECS_Unarmed) //맨손 -> 권총
{
CharacterState = ECharacterState::ECS_ArmedWithPistol;
CurrentWeapon = WeaponList[0];
}
if(CurrentWeapon)
{
CurrentWeapon->SetOwner(this);
CurrentWeapon->SetInstigator(this);
}
if (KannaTPSOverlay)
{
if (CurrentWeapon)
{
KannaTPSOverlay->ShowAmmoText();
KannaTPSOverlay->SetTotalAmmoText(CurrentWeapon->GetTotalAmmo());
KannaTPSOverlay->SetCurrentAmmoText(CurrentWeapon->GetCurrentAmmo());
}
else
{
KannaTPSOverlay->HideAmmoText();
}
}
}
KannaTPSOverlay가 null이 아니면,
- CurrentWeapon이 null이 아니면 탄약 개수 보여주기
- CurrentWeapon이 null, 즉 맨손이라면 탄약 UI 숨기기
이렇게 UI 시스템은 완성되었다.
참고로, Pistol의 탄약 변수의 기본 값은 다음과 같이 설정해주었다.
// Sets default values
APistol::APistol()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
FireMode = EFireMode::EFM_SEMIAUTO;
Range = 10000.f;
Damage = 35.f;
MaxAmmo = 17;
}
// Called when the game starts or when spawned
void APistol::BeginPlay()
{
Super::BeginPlay();
if (KannaCharacter)
{
KannaCharacter->AddWeaponToList(this); //권총은 시작할 때부터 가지고 있어야 한다.
this->AttachToComponent(KannaCharacter->GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, FName("Pistol_Socket"));
}
TotalAmmo = 255;
CurrentAmmo = 17;
}
탄창 용량이 17발로 권총 치고 좀 많은데, 실제로 칸나의 전용무기의 모델인 글록 17이 탄창에 17발이 들어간다고 한다.
총을 쏘고, 재장전함에 따라 탄약 개수가 잘 들어드는 것을 확인할 수 있었다.
이제 재장전 애니메이션을 넣어볼 것이다.
'언리얼 엔진 5 > 개발 일지' 카테고리의 다른 글
[UE5] 블루아카이브 TPS게임 개발일지 (41) - 장전 애니메이션 구현 2 (0) | 2024.01.14 |
---|---|
[UE5] 블루아카이브 TPS게임 개발일지 (40) - 장전 애니메이션 구현 1 (0) | 2024.01.14 |
[UE5] 블루아카이브 TPS게임 개발일지 (38) - 탄약 UI 구현 1 (0) | 2024.01.14 |
[UE5] 블루아카이브 TPS게임 개발일지 (37) - 엄폐 시스템 구현 7 (0) | 2024.01.10 |
[UE5] 블루아카이브 TPS게임 개발일지 (36) - 엄폐 시스템 구현 6 (0) | 2024.01.10 |