added Health and Mana widgets and visibility based on player distance

This commit is contained in:
Caleb Buhungiro
2025-06-27 15:36:48 +08:00
parent c47347e635
commit 05e06a57be
8 changed files with 149 additions and 8 deletions

View File

@@ -3,10 +3,19 @@
#include "Crunch/Public/Character/CCharacter.h"
#include "Components/WidgetComponent.h"
#include "GAS/CAbilitySystemComponent.h"
#include "GAS/CAttributeSet.h"
#include "Kismet/GameplayStatics.h"
#include "Widgets/OverHeadStatsGauge.h"
void ACCharacter::BeginPlay()
{
Super::BeginPlay();
ConfigureOverHeadStatusWidget();
}
ACCharacter::ACCharacter()
{
PrimaryActorTick.bCanEverTick = true;
@@ -18,6 +27,8 @@ ACCharacter::ACCharacter()
* This is also valid
* CAttributeSet = CAbilitySystemComponent->GetSet<UCAttributeSet>();
**/
OverHeadWidgetComponent = CreateDefaultSubobject<UWidgetComponent>("OverHead Widget Component");
OverHeadWidgetComponent->SetupAttachment(GetRootComponent());
}
void ACCharacter::ServerSideInit()
@@ -31,8 +42,60 @@ void ACCharacter::ClientSideInit()
CAbilitySystemComponent->InitAbilityActorInfo(this, this);
}
bool ACCharacter::IsLocallyControlledByPlayer() const
{
return GetController() && GetController()->IsLocalPlayerController();
}
/**
* this is for the AI controller pawns
* this is only called on the server
* @param NewController
*/
void ACCharacter::PossessedBy(AController* NewController)
{
Super::PossessedBy(NewController);
if (NewController && !NewController->IsPlayerController())
{
ServerSideInit();
}
}
UAbilitySystemComponent* ACCharacter::GetAbilitySystemComponent() const
{
return CAbilitySystemComponent;
}
void ACCharacter::ConfigureOverHeadStatusWidget()
{
if (!OverHeadWidgetComponent) return;
if (IsLocallyControlledByPlayer())
{
OverHeadWidgetComponent->SetHiddenInGame(true);
return;
}
auto OverHeadStatsGauge = Cast<UOverHeadStatsGauge>(OverHeadWidgetComponent->GetUserWidgetObject());
if (OverHeadStatsGauge)
{
OverHeadStatsGauge->ConfigureWithASC(GetAbilitySystemComponent());
OverHeadWidgetComponent->SetHiddenInGame(false);
GetWorldTimerManager().ClearTimer(HeadStatGaugeVisibilityUpdateTimerHandle);
GetWorldTimerManager().SetTimer(
HeadStatGaugeVisibilityUpdateTimerHandle,
this,
&ThisClass::UpdateHeadStatGaugeVisibility,
HeadStatGaugeVisibilityCheckUpdateGap,
true);
}
}
void ACCharacter::UpdateHeadStatGaugeVisibility()
{
auto LocalPlayerPawn = UGameplayStatics::GetPlayerPawn(this, 0);
if (LocalPlayerPawn)
{
const float DistSquared = FVector::DistSquared(GetActorLocation(), LocalPlayerPawn->GetActorLocation());
OverHeadWidgetComponent->SetHiddenInGame(DistSquared > HeadStatGaugeVisibilityRangeSquared);
}
}

View File

@@ -16,12 +16,10 @@ void UGameplayWidget::NativeConstruct()
HealthBar->SetAndBoundToGameplayAttribute(
OwnerAbilitySystemComponent,
UCAttributeSet::GetHealthAttribute(),
UCAttributeSet::GetMaxHealthAttribute()
);
UCAttributeSet::GetMaxHealthAttribute());
ManaBar->SetAndBoundToGameplayAttribute(
OwnerAbilitySystemComponent,
UCAttributeSet::GetManaAttribute(),
UCAttributeSet::GetMaxManaAttribute()
);
UCAttributeSet::GetMaxManaAttribute());
}
}

View File

@@ -0,0 +1,22 @@
// Multiplayer By Caleb
#include "Widgets/OverHeadStatsGauge.h"
#include "GAS/CAttributeSet.h"
#include "Widgets/ValueGauge.h"
void UOverHeadStatsGauge::ConfigureWithASC(UAbilitySystemComponent* AbilitySystemComponent)
{
if (AbilitySystemComponent)
{
HealthBar->SetAndBoundToGameplayAttribute(
AbilitySystemComponent,
UCAttributeSet::GetHealthAttribute(),
UCAttributeSet::GetMaxHealthAttribute());
ManaBar->SetAndBoundToGameplayAttribute(
AbilitySystemComponent,
UCAttributeSet::GetManaAttribute(),
UCAttributeSet::GetMaxManaAttribute());
}
}

View File

@@ -7,6 +7,7 @@
#include "GameFramework/Character.h"
#include "CCharacter.generated.h"
class UWidgetComponent;
class UCAbilitySystemComponent;
class UCAttributeSet;
@@ -15,10 +16,17 @@ class CRUNCH_API ACCharacter : public ACharacter, public IAbilitySystemInterface
{
GENERATED_BODY()
protected:
virtual void BeginPlay() override;
public:
ACCharacter();
void ServerSideInit();
void ClientSideInit();
bool IsLocallyControlledByPlayer() const;
// Only called on the server
virtual void PossessedBy(AController* NewController) override;
/********************************************************************************************/
/* Gameplay Ability */
/********************************************************************************************/
@@ -26,8 +34,24 @@ public:
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
private:
UPROPERTY(EditDefaultsOnly, Category="Gameplay Effects")
UPROPERTY(EditDefaultsOnly, Category="Gameplay Ability")
TObjectPtr<UCAbilitySystemComponent> CAbilitySystemComponent;
UPROPERTY(BlueprintReadOnly, Category="Gameplay Effects", meta=(AllowPrivateAccess=true))
UPROPERTY()
TObjectPtr<UCAttributeSet> CAttributeSet;
/********************************************************************************************/
/* UI */
/********************************************************************************************/
private:
UPROPERTY(VisibleDefaultsOnly, Category="UI")
TObjectPtr<UWidgetComponent> OverHeadWidgetComponent;
void ConfigureOverHeadStatusWidget();
UPROPERTY(EditDefaultsOnly, Category="UI")
float HeadStatGaugeVisibilityCheckUpdateGap = 1.f;
UPROPERTY(EditDefaultsOnly, Category="UI")
float HeadStatGaugeVisibilityRangeSquared = 10000000.f;
FTimerHandle HeadStatGaugeVisibilityUpdateTimerHandle;
void UpdateHeadStatGaugeVisibility();
};

View File

@@ -0,0 +1,28 @@
// Multiplayer By Caleb
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "OverHeadStatsGauge.generated.h"
class UValueGauge;
class UAbilitySystemComponent;
/**
*
*/
UCLASS()
class CRUNCH_API UOverHeadStatsGauge : public UUserWidget
{
GENERATED_BODY()
public:
void ConfigureWithASC(UAbilitySystemComponent* AbilitySystemComponent);
private:
UPROPERTY(meta = (BindWidget))
TObjectPtr<UValueGauge> HealthBar;
UPROPERTY(meta = (BindWidget))
TObjectPtr<UValueGauge> ManaBar;
};