이번 포스팅은 UI에 스킬의 쿨타임을 표기해보고 포션을 마셔 피를 회복해보자.
UI 스킬 쿨타임 표기하기
스킬을 쿨타임은 이미 타이머 시스템을 이용해 관리중이었다.
해당 스킬에 맞는 타이머를 빈 함수로 설정해두고 그 타이머가 현재 존재 한다면 쿨타임이라고 판단하고 스킬을 무시하도록 설계되었다.
이에 맞추어 스킬을 사용함과 동시에 UI를 업데이트 해보자.
Image Mask 효과 내기
UI의 아이템과 스킬 칸은 이런식으로 되어있다.
Retainer Box를 통해 유니티의 Image Mask 효과를 냈다.
내가 가지고 있는 UI의 포션과 스킬 아이콘은 정사각형이지만, 지금 적용해야 될 이미지는 Hex 모양이기 때문에 이미지 마스크가 필요했다.
언리얼에서 이미지를 마스크 하는 방법은 나름 간단했다. Retainer Box와 머티리얼을 이용해 그 작업을 쉽게할 수 있었다.
Retainer Box는 렌더링 대상을 나중에 화면에 렌더링하기 전에 먼저 자식 위젯을 렌더링 대상에 렌더링한다.
이를 통해 UI 가 실제로 기본 게임 렌더링 빈도보다 덜 자주 렌더링될 수 있도록 주파수와 위상을 모두 제어할 수 있다.
또한 간단한 후처리를 적용하기 위해 위젯을 그린 후 렌더링 대상에 재료를 적용할 수 있는 부수적 이점도 있다.
그러니 여기에 마스크에 사용될 머티리얼만 적용하면 된다!
먼저 우리가 사용할 마스크의 RGB와 A를 곱해 외곽을 제거하고 육각형 모양으로 남긴다.
그리고 우리가 사용할 Target param에서 RBG 색을 Target 텍스처를 그대로 유지하며 투명도를 그전에 마스킹 해둔 것으로 변경하게 된다. 이렇게 함으로써 이런 네모난 스킬 아이콘에서 육각형을 얻을 수 있다.
따라서 이렇게 스킬 UI를 만들 수 있다.
쿨타임 처리
쿨타임의 경우 Progress bar를 이용한다.
타이머를 이용해 Progress Bar를 채워주도록 하자.
설정은 이렇게 해준다.
코드는 간결하다.
ElapsedTime1 = 0.f;
if (GetWorld())
{
GetWorld()->GetTimerManager().SetTimer(
SkillBar1Handle,
[this, LocalDuration]()
{
ElapsedTime1 += 0.01f;
float Percent = 1.0f - FMath::Clamp(ElapsedTime1 / LocalDuration, 0.0f, 1.0f);
if (SkillBar1)
{
SkillBar1->SetPercent(Percent);
}
if (ElapsedTime1 >= LocalDuration)
{
GetWorld()->GetTimerManager().ClearTimer(SkillBar1Handle);
}
},
0.01f,
true
);
}
타이머를 이용해 0.01초 마다 반복하는데 목표 시간(예를 들어 10초에서 0초까지)까지 값을 계산해 퍼센트를 설정해준다.
이렇게 해서 스킬 쿨타임을 간단하게 구현할 수 있었다.
포션 마시기
포션을 마시는건 1번을 누르면 할 수 있게 했다.
EnhancedInput->BindAction(PotionAction, ETriggerEvent::Triggered, this, &URASInputComponent::HandlePress1);
void URASInputComponent::HandlePress1()
{
ARASPlayer* OwnerPlayer = Cast<ARASPlayer>(GetOwner());
if (URASCombatComponent* CombatComponent = OwnerPlayer->GetCombatComponent())
{
CombatComponent->UsePotion();
}
}
UsePotion을 하게 되면 피를 회복하고 UI를 업데이트하며 지정된 몽타주를 실행한다.
void URASCombatComponent::UsePotion()
{
if (CombatState != EPlayerCombatState::Idle) return;
if (PotionCount <= 0) return;
if (GetWorld()->GetTimerManager().IsTimerActive(PotionTimer)) return;
URASStatComponent* Stat = OwnerPlayer->GetStat();
if (Stat == nullptr) return;
GetWorld()->GetTimerManager().SetTimer(
PotionTimer,
[this]()
{
},
3.f,
false);
OwnerPlayer->GetUIComponent()->SetIconProgressBar(3, 3.f, PotionCount);
Stat->SetHp(Stat->GetHp() + Stat->GetMaxHp() * 0.6f);
CombatState = EPlayerCombatState::UsingItem;
PotionCount--;
URASPlayerAnimComponent* MyAnimInstance = OwnerPlayer->GetAnimComponent();
if (MyAnimInstance == nullptr) return;
MyAnimInstance->PlayMontageWithSection(MyAnimInstance->GetMontageByName(TEXT("Potion")), TEXT("Potion"), 1.f,
[this](UAnimMontage* Montage, bool bInterrupted)
{
CombatState = EPlayerCombatState::Idle;
});
}
몽타주는 Upper Body Slot을 이용해 걸어다니면서 포션을 마실 수 있게 Blend 해주었다.
결과
'Unreal Engine 5 > ProjectRAS' 카테고리의 다른 글
[UE5] ProjectRAS - 메인 Title UI와 메뉴 UI 만들기 (0) | 2025.06.11 |
---|---|
[UE5] ProjectRAS - 몬스터 스폰하기, Clothes 적용하기 (0) | 2025.05.28 |
[UE5] ProjectRAS - 보스 패턴 제작하기 (0) | 2025.05.16 |
[UE5] ProjectRAS - Map Generator (0) | 2025.04.23 |
[UE5] ProjectRAS - 맵 디자인 및 블프화 (0) | 2025.04.16 |