Hi,
I am using Attribute Sets to store attributes like Health. Whenever health is modified by a Gameplay Effect, I would like to clamp the value between 0 and MaxHealth.
What’s the difference between PreAttributeChanged and PreAttributeBaseChange? Is there a difference between an Attribute Base value and an Attribute value?
One is called when I apply a Gameplay Effect with a modifier, but the other is called when I apply a Gameplay Effect with a UGameplayEffectExecutionCalculation that outputs a modifier. Health may be modified in either way, so do I need to clamp the Health value in both functions, or I should be doing that somewhere else?
Thanks.
Sheri
Sheri,
Here is a description that was given to me:
Final Value = AttributeMods(Base Value)
Final value is basically “the value of the float property on your UAttributeSet”. Base Value refers to the internal base value of the attribute FAggregator that is managed in the UAbilitySystemComponent.
“AttributeMods” is a function that does operations on the base value,
such as addition, multiplication, etc. That function is FAggregator::EvaluateWithBase.
The mods are data that are acting on the base value. Things (GameplayEffects mainly)
either act directly on the Base Value, or they add mods into the FAggregator that will
be used by EvaluateWithBase to find the Final Value of the attribute.
The safest bet would just be to perform the clamp in both to guarantee you’re always within a valid range.
It seems like this was initially intended to be to split how different changes affect changes to stats.
For example, in an RPG like game you may have a “increase health by 10%” effect, vs. just taking damage.
Thanks,
Jon N.
1 Like
So using Aggregators (through a UGameplayEffectExecutionCalculation ) will result in the Aggregator collecting and applying all the Mods before changing the BaseValue, but giving a Mod directly on the GameplayEffect may not use Aggregators?
Actually, looking at this again, at least in the ways that my project currently uses GEs and Attribute Sets, PreAttributeChange is always called, either on its own, or after PreAttributeBaseChange.
I’ll keep the implementation in both for now, but duplicating the code doesn’t feel right.
Thank you for the additional information!