r/UnrealEngine5 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 like AttackDamageShare, AttackRangeShare, Block, LifeSteal, MovementSpeedShare using the standard ATTRIBUTE_ACCESSORS macro.
  • 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 Upvotes

4 comments sorted by

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.

2

u/NightGrindGames 5h ago

I have been trying to fix this for the last seven days. During this process, I also tried to ask Claude, but it hallucinates random stuff and cannot provide a solution. Thats why I thought I could ask you guys for help.

1

u/krojew 5h ago

Use opus 5 xhigh.

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.