It’s really an old post, but I went into this issue recently. Hope my solution can help others.
Using the workaround provided by @SteveProteau can be a bit inconvenient, and it does not support blending values between curves if multiple montages have curves with the same name. For instance, if you have two montages, A and B, active at the same time, and both of them have a curve X, you might want to get a blended result of curve X that respects the values provided by both A and B.
Here is my solution, you need to implement a custom anim instance like this:
UCLASS(Config = Game)
class UMyAnimInstance : public UAnimInstance
{
GENERATED_BODY()
public:
UMyAnimInstance(const FObjectInitializer& ObjectInitializer);
// keep montage curve value when blending in/out
UFUNCTION(BlueprintCallable, BlueprintPure = false)
float GetFadelessCurveValue(FName CurveName) const;
bool GetFadelessCurveValue(FName CurveName, float& OutValue) const;
};
float UMyAnimInstance::GetFadelessCurveValue(FName const CurveName) const
{
float Value = 0.f;
GetFadelessCurveValue(CurveName, Value);
return Value;
}
bool UMyAnimInstance::GetFadelessCurveValue(FName const CurveName, float& OutValue) const
{
float TotalWeight{};
TArray<TTuple<float, float>, TInlineAllocator<5>> CurvesWithWeight{};
for (FAnimMontageInstance const* Instance : MontageInstances)
{
if (!Instance->Montage || !Instance->Montage->HasCurveData(CurveName))
{
continue;
}
float const Weight = Instance->GetWeight();
float const Position = Instance->GetPosition();
float const CurveValue = Instance->Montage->EvaluateCurveData(CurveName, Position);
CurvesWithWeight.Emplace(CurveValue, Weight);
TotalWeight += Weight;
}
if (TotalWeight <= 0 || FMath::IsNearlyZero(TotalWeight))
{
return false;
}
OutValue = 0.0f;
for (auto const& [CurveValue, Weight] : CurvesWithWeight)
{
OutValue += CurveValue * Weight / TotalWeight;
}
return true;
}
Then you can get correct curve values by GetFadelessCurveValue
function.