Root motion doesn't play correctly for some montages when bAlwaysUpdateSourcePose is true and root motion mode is set to Root Motion From Everything

Hi,

Recently, I was playing a montage on `Default Slot` and 1) I had set `Always Update Source Pose` to true, and 2) I had set `Root Motion Mode` to `Root Motion From Everything`. I noticed that the montage root motion was not playing correctly even though its blend weight was 1. This issue disappeared if I either 1) Set `Always Update Source Pose` to false, or 2) set `Root Motion Mode` to `Root Motion From Montages Only`.

What was strange was that the issue only happened for this particular montage. I wonder if it is because this montage’s motion was more complicated than the other ones that I tried (its root rotates 180 degrees while moving both horizontally and vertically).

Is this a known issue? Should I avoid having `Root Motion From Everything` when `Always Update Source Pose` is true and vice versa?

Kind regards,

Maryam

Hi, sorry for the delay. This is likely a bug with root motion from everything which has not previously been noticed due to the “Always Update Source Pose” setting, as well as that Root Motion from everything is not used extensively in shipping products for performance reasons.

I believe the reason for the issue is that the root motion from the source pose is being blended in with the root motion from the montage based on the Tick Record RootMotionWeight.

(See FAnimSync::TickAssetPlayerInstances)

I have yet to reproduce this bug, but just from looking at the code, it looks like the problem is that FAnimNode_Slot::Update_AnyThread, when it updates the source pose does this:

const bool bUpdateSource = bAlwaysUpdateSourcePose || FAnimWeight::IsRelevant(WeightData.SourceWeight); if (bUpdateSource) { const float SourceWeight = FMath::Max(FAnimWeight::GetSmallestRelevantWeight(), WeightData.SourceWeight); Source.Update(Context.FractionalWeight(SourceWeight)); }it should be calling Context.FractionalWeightAndRootMotion(SourceWeight) in order to have the tick records end up with zero root motion weight.

If you are able to try out that change, let me know if it fixes the issue.

Actually, I am wrong about that potential solution.. FractionalWeight is the correct call to be making there, as that should affect the root motion weight as well.

But that would be the place to start debugging… Tick records from inside the Source update should have 0 weight, and thus contribute nothing to root motion when it is accumulated in FAniomSync::TickAssetPlayerInstances. (but perhaps that’s not what’s happening)

For some more details, the montage root motion should get added to the Extracted root motion from the RootMotionBlendQueue in UAnimInstance::PostUpdateAnimation.

I’d debug This block of code, and expect the first part (which should be the non montage root motion) to be zero, and the second part to have the root motion from your montage which you want.

`if(Proxy.GetExtractedRootMotion().bHasRootMotion)
{
FTransform ProxyTransform = Proxy.GetExtractedRootMotion().GetRootMotionTransform();
ProxyTransform.NormalizeRotation();
ExtractedRootMotion.Accumulate(ProxyTransform);
Proxy.GetExtractedRootMotion().Clear();
}

// blend in any montage-blended root motion that we now have correct weights for
for(const FQueuedRootMotionBlend& RootMotionBlend : RootMotionBlendQueue)
{
const float RootMotionSlotWeight = GetSlotNodeGlobalWeight(RootMotionBlend.SlotName);
const float RootMotionInstanceWeight = RootMotionBlend.Weight * RootMotionSlotWeight;
ExtractedRootMotion.AccumulateWithBlend(RootMotionBlend.Transform, RootMotionInstanceWeight);
}`