Let's talk

GKLAttributeSet.h

Source/GASKitLite/Public/GKLAttributeSet.h Raw Download ZIP

Click a line number to link it. Shift-click to select a range.

1// Copyright (c) 2026 Reignance Studios. MIT License, see LICENSE.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "AbilitySystemComponent.h"
7#include "AttributeSet.h"
8#include "GKLAttributeSet.generated.h"
9
10#define GKL_ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
11 GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
12 GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
13 GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
14 GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
15
16/**
17 * Health, Stamina and Mana for a multiplayer player.
18 *
19 * - Every gameplay attribute replicates with an OnRep that calls GAMEPLAYATTRIBUTE_REPNOTIFY,
20 * registered with REPNOTIFY_Always, so predicted values on the owning client are confirmed.
21 * - Values are clamped twice: PreAttributeChange clamps what queries return, and
22 * PostGameplayEffectExecute clamps the base value that instant and periodic effects change.
23 * - Damage is a server-only meta attribute: effects add to it, PostGameplayEffectExecute
24 * moves it into Health and sends Event.Death when Health reaches 0.
25 */
26UCLASS()
27class GASKITLITE_API UGKLAttributeSet : public UAttributeSet
28{
29 GENERATED_BODY()
30
31public:
32 UGKLAttributeSet();
33
34 virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
35 virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;
36 virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
37
38 /** Server only. Refills Health, Stamina and Mana and re-arms the death event. Called on respawn. */
39 void ResetToMax();
40
41 UPROPERTY(BlueprintReadOnly, Category = "GASKit Lite|Health", ReplicatedUsing = OnRep_Health)
42 FGameplayAttributeData Health;
43 GKL_ATTRIBUTE_ACCESSORS(UGKLAttributeSet, Health)
44
45 UPROPERTY(BlueprintReadOnly, Category = "GASKit Lite|Health", ReplicatedUsing = OnRep_MaxHealth)
46 FGameplayAttributeData MaxHealth;
47 GKL_ATTRIBUTE_ACCESSORS(UGKLAttributeSet, MaxHealth)
48
49 UPROPERTY(BlueprintReadOnly, Category = "GASKit Lite|Stamina", ReplicatedUsing = OnRep_Stamina)
50 FGameplayAttributeData Stamina;
51 GKL_ATTRIBUTE_ACCESSORS(UGKLAttributeSet, Stamina)
52
53 UPROPERTY(BlueprintReadOnly, Category = "GASKit Lite|Stamina", ReplicatedUsing = OnRep_MaxStamina)
54 FGameplayAttributeData MaxStamina;
55 GKL_ATTRIBUTE_ACCESSORS(UGKLAttributeSet, MaxStamina)
56
57 UPROPERTY(BlueprintReadOnly, Category = "GASKit Lite|Mana", ReplicatedUsing = OnRep_Mana)
58 FGameplayAttributeData Mana;
59 GKL_ATTRIBUTE_ACCESSORS(UGKLAttributeSet, Mana)
60
61 UPROPERTY(BlueprintReadOnly, Category = "GASKit Lite|Mana", ReplicatedUsing = OnRep_MaxMana)
62 FGameplayAttributeData MaxMana;
63 GKL_ATTRIBUTE_ACCESSORS(UGKLAttributeSet, MaxMana)
64
65 /** Meta attribute, server only, not replicated. */
66 UPROPERTY(BlueprintReadOnly, Category = "GASKit Lite|Damage")
67 FGameplayAttributeData Damage;
68 GKL_ATTRIBUTE_ACCESSORS(UGKLAttributeSet, Damage)
69
70protected:
71 UFUNCTION()
72 void OnRep_Health(const FGameplayAttributeData& OldValue);
73 UFUNCTION()
74 void OnRep_MaxHealth(const FGameplayAttributeData& OldValue);
75 UFUNCTION()
76 void OnRep_Stamina(const FGameplayAttributeData& OldValue);
77 UFUNCTION()
78 void OnRep_MaxStamina(const FGameplayAttributeData& OldValue);
79 UFUNCTION()
80 void OnRep_Mana(const FGameplayAttributeData& OldValue);
81 UFUNCTION()
82 void OnRep_MaxMana(const FGameplayAttributeData& OldValue);
83
84private:
85 bool bOutOfHealth = false;
86};

Still desyncing in packaged builds?

Free code fixes one symptom. A Diagnostic finds the cause across your project in two days.