Game code can register listeners to when a GAS attribute changes value, for example by calling:
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(SomeAttribute).AddLambda();
These delegates are managed inside the AbilitySystemComponent's FActiveGameplayEffectsContainer::AttributeValueChangeDelegates.
Currently it's unsafe to make register or unregister a change listener while executing such a delegate, as this can cause the container to be grown or shrunk (but not always depending on container slack or attribute already registered).
There are valid use cases for registering or unregistering attribute listeners upon observing an attribute change, for example for game features that should activate or deactivate when a value crosses a threshold. Health thresholds being a primary example, so GAS usability would benefit from allowing attribute value change delegate modification from within a listener.
FGenericPlatformMisc::RaiseException (GenericPlatformMisc.cpp:740)
FDebug::CheckVerifyFailedImpl2 (AssertionMacros.cpp:663)
TArray<T>::RangeCheck (Array.h:758)
TMulticastDelegateBase<T>::Broadcast<T> (MulticastDelegateBase.h:251)
TMulticastDelegate<T>::Broadcast (DelegateSignatureImpl.inl:956)
FActiveGameplayEffectsContainer::InternalUpdateNumericalAttribute (GameplayEffect.cpp:3730)
FActiveGameplayEffectsContainer::OnAttributeAggregatorDirty (GameplayEffect.cpp:3301)
UAbilitySystemComponent::OnAttributeAggregatorDirty (AbilitySystemComponent.cpp:1906)
Invoke<T> (Invoke.h:66)
UE::Core::Private::Tuple::TTupleBase<T>::ApplyAfter<T> (Tuple.h:309)
TBaseUObjectMethodDelegateInstance<T>::ExecuteIfSafe (DelegateInstancesImpl.h:665)
TMulticastDelegateBase<T>::Broadcast<T> (MulticastDelegateBase.h:254)
TMulticastDelegate<T>::Broadcast (DelegateSignatureImpl.inl:956)
FAggregator::BroadcastOnDirty (GameplayEffectAggregator.cpp:663)
FActiveGameplayEffectsContainer::SetAttributeBaseValue (GameplayEffect.cpp:3781)
UAbilitySystemComponent::SetNumericAttributeBase (AbilitySystemComponent.cpp:388)<-- game code functions -->
Why does the REMOVE method of map container remove elements have memory leaks?
How do I set a material as a post-processing material?
How does TextureRenderTarget2D get TArray<uint8> type data?
How to delete some elements correctly when deleting an array loop?
What is the cause of the packaging error falling back to 'GameUserSettings' in ue5?
How does TArray loop correctly remove elements in blueprints?
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-221983 in the post.
0 |
Component | UE - Gameplay - Gameplay Ability System |
---|---|
Target Fix | 5.6 |
Created | Aug 16, 2024 |
---|---|
Updated | Sep 30, 2024 |