From 05e06a57bef8462df5de120cdd062780e4139de8 Mon Sep 17 00:00:00 2001 From: Caleb Buhungiro Date: Fri, 27 Jun 2025 15:36:48 +0800 Subject: [PATCH] added Health and Mana widgets and visibility based on player distance --- Content/Player/CPlayerCharacter_BP.uasset | 4 +- .../ValueGauge/OverHeadGauge_WBP.uasset | 3 + .../E/GW/FJINNVN95DAR754IU087NG.uasset | 3 + .../Crunch/Private/Character/CCharacter.cpp | 63 +++++++++++++++++++ .../Crunch/Private/Widgets/GameplayWidget.cpp | 6 +- .../Private/Widgets/OverHeadStatsGauge.cpp | 22 +++++++ Source/Crunch/Public/Character/CCharacter.h | 28 ++++++++- .../Public/Widgets/OverHeadStatsGauge.h | 28 +++++++++ 8 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 Content/Widgets/Gameplay/ValueGauge/OverHeadGauge_WBP.uasset create mode 100644 Content/__ExternalActors__/TempLevel/E/GW/FJINNVN95DAR754IU087NG.uasset create mode 100644 Source/Crunch/Private/Widgets/OverHeadStatsGauge.cpp create mode 100644 Source/Crunch/Public/Widgets/OverHeadStatsGauge.h diff --git a/Content/Player/CPlayerCharacter_BP.uasset b/Content/Player/CPlayerCharacter_BP.uasset index e5e97e8..4c0e0e9 100644 --- a/Content/Player/CPlayerCharacter_BP.uasset +++ b/Content/Player/CPlayerCharacter_BP.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3fcdc78b2ec48c68bb6738748474869f4ea4fbc46e1e156ecee87e20779b7b45 -size 30440 +oid sha256:6f3de6c95738c0ff0c8a46da49dbb45dae7a69f50e64ad84a4d713f1ac9a102d +size 31785 diff --git a/Content/Widgets/Gameplay/ValueGauge/OverHeadGauge_WBP.uasset b/Content/Widgets/Gameplay/ValueGauge/OverHeadGauge_WBP.uasset new file mode 100644 index 0000000..a76507b --- /dev/null +++ b/Content/Widgets/Gameplay/ValueGauge/OverHeadGauge_WBP.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09bf5b26e6e5481de503b305deacc308d901ebb7daed1cec9cd16ea2edfe0d9e +size 30526 diff --git a/Content/__ExternalActors__/TempLevel/E/GW/FJINNVN95DAR754IU087NG.uasset b/Content/__ExternalActors__/TempLevel/E/GW/FJINNVN95DAR754IU087NG.uasset new file mode 100644 index 0000000..4e4c2df --- /dev/null +++ b/Content/__ExternalActors__/TempLevel/E/GW/FJINNVN95DAR754IU087NG.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc2b3a5942efed5dbbd57bcd418fd9133a182531e492ed5e841fbc4c9fb729c0 +size 7432 diff --git a/Source/Crunch/Private/Character/CCharacter.cpp b/Source/Crunch/Private/Character/CCharacter.cpp index dd277f8..cab2ba4 100644 --- a/Source/Crunch/Private/Character/CCharacter.cpp +++ b/Source/Crunch/Private/Character/CCharacter.cpp @@ -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(); **/ + OverHeadWidgetComponent = CreateDefaultSubobject("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(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); + } +} diff --git a/Source/Crunch/Private/Widgets/GameplayWidget.cpp b/Source/Crunch/Private/Widgets/GameplayWidget.cpp index 4955e3a..76c04a9 100644 --- a/Source/Crunch/Private/Widgets/GameplayWidget.cpp +++ b/Source/Crunch/Private/Widgets/GameplayWidget.cpp @@ -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()); } } diff --git a/Source/Crunch/Private/Widgets/OverHeadStatsGauge.cpp b/Source/Crunch/Private/Widgets/OverHeadStatsGauge.cpp new file mode 100644 index 0000000..6dfbc38 --- /dev/null +++ b/Source/Crunch/Private/Widgets/OverHeadStatsGauge.cpp @@ -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()); + } +} diff --git a/Source/Crunch/Public/Character/CCharacter.h b/Source/Crunch/Public/Character/CCharacter.h index e1cd758..ec76353 100644 --- a/Source/Crunch/Public/Character/CCharacter.h +++ b/Source/Crunch/Public/Character/CCharacter.h @@ -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 CAbilitySystemComponent; - UPROPERTY(BlueprintReadOnly, Category="Gameplay Effects", meta=(AllowPrivateAccess=true)) + UPROPERTY() TObjectPtr CAttributeSet; + /********************************************************************************************/ + /* UI */ + /********************************************************************************************/ +private: + UPROPERTY(VisibleDefaultsOnly, Category="UI") + TObjectPtr OverHeadWidgetComponent; + void ConfigureOverHeadStatusWidget(); + + UPROPERTY(EditDefaultsOnly, Category="UI") + float HeadStatGaugeVisibilityCheckUpdateGap = 1.f; + + UPROPERTY(EditDefaultsOnly, Category="UI") + float HeadStatGaugeVisibilityRangeSquared = 10000000.f; + + FTimerHandle HeadStatGaugeVisibilityUpdateTimerHandle; + void UpdateHeadStatGaugeVisibility(); }; diff --git a/Source/Crunch/Public/Widgets/OverHeadStatsGauge.h b/Source/Crunch/Public/Widgets/OverHeadStatsGauge.h new file mode 100644 index 0000000..ff9661b --- /dev/null +++ b/Source/Crunch/Public/Widgets/OverHeadStatsGauge.h @@ -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 HealthBar; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr ManaBar; +};