총 6스택까지 사용할수있는 스킬을 구현해보겠습니다
일단 UI는 이렇습니다
중간에있는 원은 10초동안 회전할 원형프로그래스바 이며
회전이 끝나면 바깥쪽의 6개로 나누어진 프로그래스바가 한구역이 채워집니다
일단 ui를 수정해줍니다
(너무구려..)
제가 마나, 포스게이지를 위해 만들었던 움직이는 메테리얼입니다
해당 노드를 복사합니다
해당 프로그래스바에 제가 만든 메테리얼 노드들을 넣어주고 원래있던 3vector컬러 대신 넣어줍니다
원형의 프로그래스바도 회색과 흰색으로 수정해줬습니다
그냥 원형 프로그래스바 버전입니다
스킬칸 최종 UI디자인이 완성되었습니다
그럼 이제 프로그래스바 로직을 완성해보겠습니다
1. 중간에 있는 프로그래스바는 10초마다 1이됩니다
2. 중간에 있는 프로그래스바가 1이되면 바깥쪽의 프로그래스바 게이지가 한칸이 찹니다
3. 바깥쪽에있는 게이지가 꽉 차면 중간의 프로그래스바가 사라지고 더이상 움직이지않습니다
4. 스킬을 사용시 바깥쪽에 있는 게이지가 한칸이 줄어듭니다
저희가 세팅해야하는건 이미지안의 메테리얼 컬렉션값을 수정해서 프로그래스바를 조절해야합니다
위젯에서 세팅해주겠습니다
파라미터컬렉션 선언해줍니다
위젯에서 만든 파라미터컬렉션을 할당해줍니다
UMaterialParameterCollectionInstance* collectionInstance;
UMaterialParameterCollectionInstance* collectionInstanceOutter;
처음에 0으로 값을 초기화해줍니다
void USwordCharacterWidget::UpdateSInnerCountDown(float coolTime)
{
if (innerSCollection)
{
if (collectionInstance)
{
currentSCoolTime = coolTime;
GetWorld()->GetTimerManager().SetTimer(th_InnerProgressTimer,this,&USwordCharacterWidget::StartSInnerProgressBar,0.01f,true
);
}
}
}
void USwordCharacterWidget::StartSInnerProgressBar()
{
if (collectionInstance)
{
float deltaProgress = 1.0f / currentSCoolTime * 0.01f;
currentProgress += deltaProgress;
currentProgress = FMath::Clamp(currentProgress, 0.0f, 1.0f);
collectionInstance->SetScalarParameterValue(FName("Progress"), currentProgress);
if (currentProgress >= 1.0f)
{
GetWorld()->GetTimerManager().ClearTimer(th_InnerProgressTimer);
}
}
}
0.01초 주기로 Progressbar게이지를 0에서 1까지 currentSCoolTime초만큼 업데이트시켜주는 함수입니다
만약 호출할떄 5초로 호출을 한다면
5초동안 업데이트 되는걸 확인할수있습니다
그러면 이제 6스택이 되기전까지 inner프로그래스바가 계속 작동하고
바깥의 outter프로그래스바가 채워지도록 해보겠습니다
Outter선언
똑같이 초기화를 해줍니다
중간에 현재시간을 초기화해줍니다
inner프로그래스바가 1이되면 innerStack을 증가시키고 UpdateSOutterCountDown함수를 호출시켜
Outter프로그래스바를 증가시킵니다
innerStack이 6이되기전까지 계속 업데이트를 시킵니다
스택이0부터 6까지만 작동하며
프로그래스바가 현재 6등분되어있는 프로그래스바이니
6등분을 해줘서 progressIncrement변수에 담아줍니다
currentOutterProgress은 0에서 1사이의 변수값입니다
- innerStack == 1일 때 → 1 * (1/6) = 0.1667
- innerStack == 2일 때 → 2 * (1/6) = 0.3333
- innerStack == 6일 때 → 1.0
이런식으로 작동합니다
테스트를 위해 스택을 2초로 잠시 변경한뒤 확인해보겠습니다
스킬사용할때 스택을 깎는 함수도 만들어줍니다
UpdateSInnerCountDown함수는 BeginPlay에서 호출시킵니다
상시로 캐릭터가 풀스택이 아닐때를 체크해서 게이지를 계속 충전하게 만들어봅니다
만약 타이머가 작동중이 아니라면
(th_InnerProgressTimer가작동중이 아니라면)
다시 타이머를 돌리는 UpdateSOutterDownStack함수를 호출합니다
스택이 다 차면 hidden 다시 타이머가 돌아갈때 다시 visible로 변경해줬습니다
void USwordCharacterWidget::UpdateSInnerCountDown(float coolTime)
{
if (innerSCollection)
{
if (collectionInstance)
{
currentSCoolTime = coolTime;
currentProgress = 0.0f;
if (innerProgressBar)
{
innerProgressBar->SetVisibility(ESlateVisibility::Visible);
collectionInstance->SetScalarParameterValue(FName("Progress"), currentProgress);
}
GetWorld()->GetTimerManager().SetTimer(th_InnerProgressTimer,this,&USwordCharacterWidget::StartSInnerProgressBar,0.01f,true);
}
}
}
void USwordCharacterWidget::StartSInnerProgressBar()
{
if (collectionInstance)
{
float deltaProgress = 1.0f / currentSCoolTime * 0.01f;
currentProgress += deltaProgress;
currentProgress = FMath::Clamp(currentProgress, 0.0f, 1.0f);
collectionInstance->SetScalarParameterValue(FName("Progress"), currentProgress);
if (currentProgress >= 1.0f)
{
GetWorld()->GetTimerManager().ClearTimer(th_InnerProgressTimer);
innerStack++;
UpdateSOutterCountDown();
if (innerStack >= 6)
{
if (collectionInstanceOutter)
{
innerProgressBar->SetVisibility(ESlateVisibility::Hidden);
}
}
else
{
UpdateSInnerCountDown(currentSCoolTime);
}
}
}
}
void USwordCharacterWidget::UpdateSOutterCountDown()
{
if (collectionInstanceOutter)
{
if (innerStack >= 0 && innerStack <= 6)
{
float progressIncrement = 1.0f / 6.0f; // 6등분
float currentOutterProgress = 0.0f;
currentOutterProgress = innerStack * progressIncrement;
currentOutterProgress = FMath::Clamp(currentOutterProgress, 0.0f, 1.0f);
collectionInstanceOutter->SetScalarParameterValue(FName("Progress"), currentOutterProgress);
}
}
}
void USwordCharacterWidget::UpdateSOutterDownStack()
{
if (innerStack > 0)
{
innerStack--;
UpdateSOutterCountDown();
if (!GetWorld()->GetTimerManager().IsTimerActive(th_InnerProgressTimer))
{
UpdateSInnerCountDown(currentSCoolTime);
}
}
}
그리고 스택이 있을때만 공격 가능하게 설정해줬습니다
innerprogressbar가 쿨타임마다 한바퀴돌고 1이되면 outterprogressbar가 1씩 채워지며
기술을 사용하면 스택이 깎입니다
또한 스택이 다 차면 잠시 ui가 숨겨집니다
최종쿨타임은 6초로 설정해줬습니다
'Unreal5 프로젝트 다이어리' 카테고리의 다른 글
Unreal - 미니맵 만들기 (0) | 2025.04.25 |
---|---|
Unreal - 마우스 커서 바꾸기 (0) | 2025.04.25 |
Unreal - 원형 프로그래스바(ProgressBar) 만들기 (0) | 2025.04.24 |
Unreal - Ghost Trail(고스트 트레일) 잔상 (0) | 2025.04.23 |
Unreal - Radial Blur 기법 (신속 블러) (0) | 2025.04.22 |