일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- Unreal Engine
- CTF
- local prediction
- animation
- attribute
- gas
- 게임개발
- 언리얼엔진
- photon fusion2
- MAC
- rpc
- gravity direction
- ability task
- os
- unity
- nanite
- Replication
- Aegis
- listen server
- 유니티
- 게임 개발
- gameplay effect
- ret2libc
- 언리얼 엔진
- map design
- Multiplay
- dirty cow
- gameplay ability system
- gameplay tag
- UI
Archives
- Today
- Total
Replicated
** [Drag Down] UI 자체 Local Prediction 구현 ** 본문
진짜 값을, 그것도 주기적으로 변하는 걸 로컬 프레딕션 하려고 했는데, 너무 위험하다.
보이는 값이 프레딕션 되도록 처리해보자!
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UI/DDGASUserWidget.h"
#include "GameplayEffectTypes.h"
#include "DDGASStaminaBarUserWidget.generated.h"
/**
*
*/
UCLASS()
class DRAGDOWN_API UDDGASStaminaBarUserWidget : public UDDGASUserWidget
{
GENERATED_BODY()
public:
UDDGASStaminaBarUserWidget();
virtual void SetAbilitySystemComponent(AActor* InOwner) override;
void UpdateStaminaBar();
protected:
virtual void OnStaminaChanged(const FOnAttributeChangeData& ChangeData);
virtual void OnMaxStaminaChanged(const FOnAttributeChangeData& ChangeData);
protected:
UPROPERTY(meta = (BindWidget))
TObjectPtr<class UProgressBar> PbStaminaBar;
float CurrentStamina = 0.0f;
float CurrentMaxStamina = 0.1f;
// Preidction
private:
void PredictStaminaUI();
float PredictionDeltaValue;
float PredictionPeriod;
FTimerHandle StaminaPredictionHandle;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "UI/DDGASStaminaBarUserWidget.h"
#include "AbilitySystemComponent.h"
#include "Attribute/DDAttributeSet.h"
#include "Components/ProgressBar.h"
#include "DragDown.h"
UDDGASStaminaBarUserWidget::UDDGASStaminaBarUserWidget()
{
PredictionDeltaValue = 5.0f;
PredictionPeriod = 0.5f;
}
void UDDGASStaminaBarUserWidget::SetAbilitySystemComponent(AActor* InOwner)
{
Super::SetAbilitySystemComponent(InOwner);
if (ASC)
{
ASC->GetGameplayAttributeValueChangeDelegate(UDDAttributeSet::GetStaminaAttribute()).AddUObject(this, &UDDGASStaminaBarUserWidget::OnStaminaChanged);
ASC->GetGameplayAttributeValueChangeDelegate(UDDAttributeSet::GetMaxStaminaAttribute()).AddUObject(this, &UDDGASStaminaBarUserWidget::OnMaxStaminaChanged);
//UE_LOG(LogCS, Log, TEXT("[NetMode : %d] SetAbilitySystemComponent"), GetWorld()->GetNetMode());
const UDDAttributeSet* CurrentAttributeSet = ASC->GetSet<UDDAttributeSet>();
if (CurrentAttributeSet)
{
CurrentStamina = CurrentAttributeSet->GetStamina();
CurrentMaxStamina = CurrentAttributeSet->GetMaxStamina();
if (CurrentMaxStamina > 0.0f)
{
UpdateStaminaBar();
}
else
{
UE_LOG(LogDD, Warning, TEXT("CurrentMaxEnergy is 0"));
}
}
else
{
UE_LOG(LogDD, Warning, TEXT("CurrentAttributeSet is null!"));
}
}
else
{
UE_LOG(LogDD, Warning, TEXT("ASC is null! Ensure that the Ability System Component is properly initialized before calling this function."));
}
if ( !Owner->HasAuthority() )
{
GetWorld()->GetTimerManager().SetTimer(StaminaPredictionHandle, this, &UDDGASStaminaBarUserWidget::PredictStaminaUI,
PredictionPeriod, true, 0.0f);
}
}
void UDDGASStaminaBarUserWidget::UpdateStaminaBar()
{
if (PbStaminaBar)
{
if ( !Owner->HasAuthority() )
{
UE_LOG(LogDD, Log, TEXT("[NetMode %d] UpdateEnergyBar : %f / %f"), GetWorld()->GetNetMode(), CurrentStamina, CurrentMaxStamina);
}
PbStaminaBar->SetPercent(CurrentStamina / CurrentMaxStamina);
}
}
void UDDGASStaminaBarUserWidget::OnStaminaChanged(const FOnAttributeChangeData& ChangeData)
{
//UE_LOG(LogDD, Log, TEXT("[NetMode %d]OnEnergyChanged"), GetWorld()->GetNetMode());
CurrentStamina = ChangeData.NewValue;
UpdateStaminaBar();
}
void UDDGASStaminaBarUserWidget::OnMaxStaminaChanged(const FOnAttributeChangeData& ChangeData)
{
CurrentMaxStamina = ChangeData.NewValue;
UpdateStaminaBar();
}
void UDDGASStaminaBarUserWidget::PredictStaminaUI()
{
CurrentStamina += PredictionDeltaValue;
UpdateStaminaBar();
}
이런식으로 내부 CurrentStamina를 조절한다
일단 테스트용으로 0.5초에 한 번 작동하도록 했다
이제 다음은 UI가 보간되어 부드럽게 움직이도록 할 것이다
'언리얼 엔진 > Drag Down (캡스톤 디자인)' 카테고리의 다른 글
[Drag Down] Gameplay Tag 관리 리팩토링 (0) | 2025.04.06 |
---|---|
[Drag Down] 액션 어빌리티 리팩토링 (0) | 2025.04.06 |
[Drag Down] 주기적으로 호출되는 이펙트를 예측 실행하면 안된다.. (0) | 2025.04.05 |
[Drag Down] Local Prediction 스테미나 자동 회복 시스템 Engine & Bug in Gameplay Effect (비추천) (0) | 2025.04.05 |
[Drag Down] 스테미나 자동 회복 시스템 (문제.. 동기화가 느림) (0) | 2025.04.03 |