// Copyright (c) 2026 Reignance Studios. MIT License, see LICENSE. // Example only: copy into your game module and rename the RSExample prefix. #pragma once #include "CoreMinimal.h" #include "AttributeSet.h" #include "AbilitySystemComponent.h" #include "RSExampleAttributeSet.generated.h" #define RS_ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \ GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \ GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \ GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \ GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName) UCLASS() class URSExampleAttributeSet : public UAttributeSet { GENERATED_BODY() public: UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category = "Attributes") FGameplayAttributeData Health; RS_ATTRIBUTE_ACCESSORS(URSExampleAttributeSet, Health) UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Stamina, Category = "Attributes") FGameplayAttributeData Stamina; RS_ATTRIBUTE_ACCESSORS(URSExampleAttributeSet, Stamina) virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; protected: // GAMEPLAYATTRIBUTE_REPNOTIFY keeps client prediction intact: it tells the // ASC about the new server value so predicted changes are re-applied on top. UFUNCTION() void OnRep_Health(const FGameplayAttributeData& OldValue); UFUNCTION() void OnRep_Stamina(const FGameplayAttributeData& OldValue); };