Gameplay attributes are not clamped and have higher values internally.

When I refill mana by 100 points(with gameplay effect) . On my Hud I still see 100, but internally character has more and it keeps 100 until falls below 100 so I can actually see changes.

Where do I clamp values properly? I tried reading Tranek Git Documentaiton but is so confusing as it points to this methods…

I tried 2 methods of clamping my Attributes.

#include "BasicAttributeSet.h"

void UBasicAttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
{
	if (Attribute == GetHealthAttribute()) {
		NewValue = FMath::Clamp<float>(NewValue, 0.f, MaxHealth.GetCurrentValue());
	}

	if (Attribute == GetManaAttribute()) {
		NewValue = FMath::Clamp<float>(NewValue, 0.f, MaxMana.GetCurrentValue());
		//NewValue = FMath::Clamp<float>(NewValue, 0.f, 60.f);
	}
}

void UBasicAttributeSet::PostAttributeChange(const FGameplayAttribute& Attribute, float OldValue, float NewValue)
{
	if (Attribute == GetHealthAttribute()) {
		NewValue = FMath::Clamp<float>(NewValue, 0.f, MaxHealth.GetCurrentValue());
	}

	if (Attribute == GetManaAttribute()) {
		NewValue = FMath::Clamp<float>(NewValue, 0.f, MaxMana.GetCurrentValue());
	}
}

In the AttributeSet header, there is this comment on the PreAttributeChange function:

This function is meant to enforce things like "Health = Clamp(Health, 0, MaxHealth)"

I’m pretty sure this means you need to also clamp your actual value and not just the new value. I’m not familiar with this plugin and this class, so I can’t really give you an exact line of code.

Edit:
I also read a bit of tranek’s documentation. I found this note about AttributeSets:

Note: Any clamping that happens here does not permanently change the modifier on the ASC . It only changes the value returned from querying the modifier. This means anything that recalculates the CurrentValue from all of the modifiers like GameplayEffectExecutionCalculations and ModifierMagnitudeCalculations need to implement clamping again.

Maybe experiment with this as well.

Hi,

You can use PostGameplayEffectExecute function.

For example:

void UAuraAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
if (Data.EvaluatedData.Attribute == GetHealthAttribute())
	{
		SetHealth(FMath::Clamp(GetHealth(), 0.f, GetMaxHealth()));
	}
	if (Data.EvaluatedData.Attribute == GetManaAttribute())
	{
		SetMana(FMath::Clamp(GetMana(), 0.f, GetMaxMana()));
	}
}

Note: you may want to keep PreAttributeChange or PostAttributeChange, no harm.

1 Like