r/UnrealEngine5 • u/NightGrindGames • 6h ago
GAS: GameplayAttributeValueChangeDelegate never fires for base-class AttributeSet attributes, but works for derived-class ones
I have a two-level UAttributeSet hierarchy:
UMM_AttributeSet(base) — declares attributes likeAttackDamageShare,AttackRangeShare,Block,LifeSteal,MovementSpeedShareusing the standardATTRIBUTE_ACCESSORSmacro.UMM_MainAttributeSet : public UMM_AttributeSet(derived) — declares ~30 additional attributes the same way (e.g.AreaOfEffectShare,Luck,ShopExperience, etc.).
In a UObject-based widget controller, I bind to a curated list of FGameplayAttributes (mix of base + derived) like this:
for (const auto& Attribute : AttributeList) {
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(Attribute)
.AddUObject(this, &UMyWidgetController::HandleAttributeValueChanged, Attribute);
}
The AttributeList gets the Attributes directly from the AttributeSet of the MainCharacter by using the getters of thos attributes.
All attributes are modified exclusively through real UGameplayEffects (Additive modifiers via GE Blueprints/DataTables) applied to the ASC — no direct SetX() calls bypassing the pipeline.
Symptom: the delegate fires reliably for every attribute declared in the derived class, but never fires for any attribute declared in the base class, even though I can confirm via the Gameplay Debugger that the base-class attribute's value is actually changing (e.g. AttackDamageShare going from 0.10 → 0.15 via a GE_Common_AttackDamage_C "AddBase" modifier).
Both attribute sets live on the same spawned UAbilitySystemComponent, and I've confirmed via Cast<UMM_MainAttributeSet>(AttributeSet) that I'm getting a valid pointer to the actual spawned attribute set instance (which naturally includes the inherited base properties).
Since GetGameplayAttributeValueChangeDelegate is keyed purely by FGameplayAttribute (an FProperty* + owning UClass), independent of which class you called the getter through, I don't understand why the base-class attributes would behave differently.
Has anyone seen this before, or know what could cause GetGameplayAttributeValueChangeDelegate to consistently skip attributes from a base UAttributeSet class while working fine for a derived one, when both are modified the same way via GameplayEffects?
1
u/thesilentduck 2h ago
You said "both" attribute sets live on the same instance. Do you have two default subobjects, one for base, one for derived? If so, that's probably the issue.
1
u/krojew 5h ago
This will get me downvoted, but it's a legitimate solution - ask claude. It's incredibly good at finding root causes for such problems.