Description

When BlendRootMotionBasedOnRootBone is true, the code in 
FAnimNode_LayeredBoneBlend::Update_AnyThread that calculates the root motion weightings for the sources doesn't appear to account for the possibility of multiple child poses being blended ontop of the base pose.  The calculations only work when there is the base pose and a single child pose.  The code responsible seems to be:

for (int32 ChildIndex = 0; ChildIndex < BlendPoses.Num(); ++ChildIndex)
{
    const float ChildWeight = BlendWeights[ChildIndex];
    if (FAnimWeight::IsRelevant(ChildWeight))
    {
       if (bHasRelevantPoses == false)
       {
          // Update cached data now we know we might be valid
          UpdateCachedBoneData(Context.AnimInstanceProxy->GetRequiredBones(), Context.AnimInstanceProxy->GetSkeleton());

          // Update weights
          FAnimationRuntime::UpdateDesiredBoneWeight(DesiredBoneBlendWeights, CurrentBoneBlendWeights, BlendWeights);
          bHasRelevantPoses = true;

          if(bBlendRootMotionBasedOnRootBone && !CurrentBoneBlendWeights.IsEmpty())
          {
             const float NewRootMotionWeight = CurrentBoneBlendWeights[0].BlendWeight;
             if(NewRootMotionWeight > ZERO_ANIMWEIGHT_THRESH)
             {
                RootMotionWeight = NewRootMotionWeight;
                RootMotionBlendPose = CurrentBoneBlendWeights[0].SourceIndex;
             }
          }
       }

       const float ThisPoseRootMotionWeight = (ChildIndex == RootMotionBlendPose) ? RootMotionWeight : RootMotionClearWeight;
       BlendPoses[ChildIndex].Update(Context.FractionalWeightAndRootMotion(ChildWeight, ThisPoseRootMotionWeight));
    }
} 

Because CurrentBoneBlendWeights[0].SourceIndex doesn't change for each child index, ThisPoseRootMotionWeight will be zero for most sources, except for the one source where ChildIndex == RootMotionBlendPose (==CurrentBoneBlendWeights[0].SourceIndex) .

Steps to Reproduce
  1. Open the attached project ([Link Removed])
  2. Open ABP_00570572
  3. In the preview viewport, switch on root motion via Character > Animation > Loop
  4. Note how no root motion is generated on the mesh
    1. This is despite the Blend Mask that is being used having the weight of Root set to 0.75
  5. Reverse the connection between Blend Poses 0 and Blend Poses 1 on the blend node so the run animation is now connected to Blend Poses 1 and the Idle to Blend Poses 0
  6. Compile and notice how root motion is now applied

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-187218 in the post.

0
Login to Vote

Won't Fix
CreatedMay 27, 2023
ResolvedMay 29, 2023
UpdatedJun 5, 2023