Description

When playing Montages with Root Motion, the sub stepper extracts root motion transform in small increments. If a Branching Point exists within the interval being extracted, the extraction range is subdivided so that the Branching Point is not crossed in a single extraction.

When Root Motion Mode of the ABP is Root Motion from Montage Only, these multiple extracted transforms are simply combined and accumulated, so the final rotation matches the full expected rotation.

However, when Root Motion from Everything is used, each extracted root motion transform is first queued in RootMotionBlendQueue and later processed by FRootMotionMovementParams::AccumulateWithBlend(). In this code path, the rotation blending does not properly accumulate the successive rotations, and it underestimates the total rotation when Branching Points cause multiple sub-steps.

This leads to a the issue: a Montage with Branching Points ends up with a smaller final rotation compared to a Montage without Branching Points, even though they use the same animation sequence.

Suggested Fix

To ensure that each sub-step’s rotation is fully accumulated rather than being averaged or diminished, modify AccumulateWithBlend so that it uses a purely multiplicative (i.e., Accumulate()) approach for rotation. For example:

 

void AccumulateWithBlend(const FTransform& InTransform, float InBlendWeight)
{
    const ScalarRegister VBlendWeight(InBlendWeight);
    if (bHasRootMotion)
    {
        // Instead of use AccumulateWithShortestRotation
        RootMotionTransform.Accumulate(InTransform, VBlendWeight);
        RootMotionTransform.SetScale3D(RootMotionScale);
        BlendWeight += InBlendWeight;
    }
    else
    {
        Set(InTransform * VBlendWeight);
        BlendWeight = InBlendWeight;
    }
    // It's better to normalize each time
    RootMotionTransform.NormalizeRotation();
}

 

 

Steps to Reproduce

Create two Montages from the same animation sequence—one without any Branching Points, and one with a Branching Point. Both are played on a character whose Root Motion Mode is set to Root Motion from Everything.

  1. Open the attached sample project.
  2. Press Alt+S to start the simulation (the character will begin moving after 5 seconds).
  3. Observe that, initially (before altering FPS), BP_TPC_Run and BP_TPC_Run_with_Branch end up facing the same direction.
  4. Stop the simulation.
  5. Enter the console command t.maxfps 5 to limit the framerate to 5 FPS.
  6. Press Alt+S to start the simulation again.

Expected Result: BP_TPC_Run and BP_TPC_Run_with_Branch should face the same direction, just as in step 4.

[Image Removed]

Actual Result: BP_TPC_Run_with_Branch rotates noticeably less than BP_TPC_Run.

[Image Removed]

Note: Limiting the FPS simply makes it easier to reproduce a scenario where the animation playback interval includes the Branching Point in a single tick, thereby triggering the bug. Low FPS is not itself the root cause.

Have Comments or More Details?

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

0
Login to Vote

Unresolved
ComponentUE - Anim - Runtime
Affects Versions5.4.4
Target Fix5.6
CreatedMar 28, 2025
UpdatedApr 7, 2025
View Jira Issue