How to get Gameplay Effect Magnitude before applying Effect?

I’m trying to get the magnitude by which a Gameplay Effect would change a certain base attribute if it where applied. Whithout actually having to apply the effect.

The only thing i found so far is this Get Gameplay Effect Magnitude node. However it needs an Active Gameplay Effect Handle Structure as input. So (if i understand correctly) the GE has to be already applied.

To clarify:
I set up armor items so that they apply Gameplay Effects to the player. These effects increase certain base attributes. Now i would like to show the potential increase of attributes for each item in a UI Tooltip. So when the player hovers the mouse over an item in his inventory a tooltip appears, showing the increase or deacrese per attribute that would result from equippng the item.

How would i go about doing that?

How are you handling these values, are they set in the GE, or are you passing them in?

For this type of situation, I tend to hold the values as floats in my UObject items, then pass in values to an ExecCalc GE using GetSetByCallerMagnitude. This way I have only 1 GE for many types of items.

For example, food items have water, protein, carbs floats. I have a single ‘ConsumeFoodGamplayEffect’ execcalc class. In there I have

float protein = FMath::Max<float>(Spec.GetSetByCallerMagnitude(FGameplayTag::RequestGameplayTag(FName("Data.Nutrition.Protein")), false, -1.0f), 0.0f);

OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(NutritionStatics().ProteinProperty, EGameplayModOp::Additive, protein));

Alternatively, you can get a reference to the GE class you are using and expand out a class defaults node. This should give access to most of your GE settings.

2 Likes

Here are some docs that go over that stuff, in section 4.5.12:

2 Likes

Please refer to the previous thread in this forum, ‘dynamic cooldowns’

1 Like

Thanks alot for the idea, that sounds like an elegant solution, i like it :slight_smile:

I’ll try and implement that over the weekend.

2 Likes

I know its abit late but maybe someone get food for thoughts from this. i found some hacky solution to predict Gameplay effect change values without dissecting whole system into bits.
First you have to deep copy ability component:

UPJCAbilitySystemComponent* UPJCAbilitySystemComponent::CreateAbilityComponentCopy()
{
	auto AbilitySystemComponentCopy = DuplicateObject(this,this->GetOwner());
	AbilitySystemComponentCopy->SetOwnerActor(this->GetOwnerActor());
	AbilitySystemComponentCopy->RemoveAllSpawnedAttributes();

	TArray<UAttributeSet*> AttributeSets;
	for(auto AttSet:this->GetSpawnedAttributes())
	{
		auto NewSet = DuplicateObject(AttSet,this->GetOwner());
		AttributeSets.Add(NewSet);
	}
	AbilitySystemComponentCopy->SetSpawnedAttributes(AttributeSets);

	
	AbilitySystemComponentCopy-> GetActiveGameplayEffectsMutable().RegisterWithOwner(AbilitySystemComponentCopy);
AbilitySystemComponentCopy-> GetActiveGameplayEffectsMutable().CloneFrom(ActiveGameplayEffects);

// this is needed if bSupressGameplayCues false.
	/*AbilitySystemComponentCopy->AbilityActorInfo = TSharedPtr<FGameplayAbilityActorInfo>(UAbilitySystemGlobals::Get().AllocAbilityActorInfo());*/
	AbilitySystemComponentCopy->bSuppressGameplayCues = true;
	return AbilitySystemComponentCopy;
}

Then create a prediction function of somekind :

		TMap<FGameplayAttribute,float> Result;
		
		auto AbilitySystemCompCopy = AbilitySystem->GetAbilityComponentCopy();
		AbilitySystemCompCopy->ApplyGameplayEffectToSelf(GameplayEffect,0,Context);
		
		TArray<FGameplayAttribute> SourceAttributes;
		AbilitySystem->GetAllAttributes(SourceAttributes);
		for(auto const &Attribute: SourceAttributes)
		{
			float SourceValue = AbilitySystem->GetNumericAttribute(Attribute);
			float TargetValue = AbilitySystemCompCopy->GetNumericAttribute(Attribute);
			if (!(TargetValue == SourceValue))
			{
				
				Result.Add(Attribute,TargetValue - SourceValue );
			}
		}
2 Likes