Custom FRootMotionSource to Override Rotation During Montage Is Not Working

질문에 참조된 게시물: [How to rotate a character toward a target during a root motion montage without using Motion [Content removed]

Hello,

I’ve run into a difficult issue while implementing a feature and would like to ask for your help.

1. Goal:

I want to maintain the root motion Translation from an animation montage, while overwriting only the Rotation in real-time to face a target every frame.

2. Methods Tried:

To implement this feature, I created a custom class (FMDRRootMotionSource_FaceTarget) that inherits from FRootMotionSource. Within its PrepareRootMotion function, I implemented logic to get the original root motion translation value using UAnimInstance::ConsumeExtractedRootMotion, calculate a new rotation to face the target, and set the final RootMotionParams.

To manage this FRootMotionSource, I created a custom Ability Task (UMDRAT_ApplyRootMotionFaceTarget) that inherits from UAbilityTask. While the task is active, I added logic to prevent control authority conflicts:

Set bUseControllerDesiredRotation and bOrientRotationToMovement on the CharacterMovementComponent to false.

3. Current Phenomenon:

Despite implementing all of the above, the character’s rotation is not being controlled by my RootMotionSource. Instead, the character still snaps instantly to the direction of movement at the start of the dash.

(Through debugging, I have confirmed that the PrepareRootMotion function is being called correctly every frame.)

Attached Files:

FMDRRootMotionSource_FaceTarget.h

FMDRRootMotionSource_FaceTarget.cpp

UMDRAT_ApplyRootMotionFaceTarget.h

UMDRAT_ApplyRootMotionFaceTarget.cpp

UMDRGA_Dash.cpp (The part that calls the Ability Task)

I would appreciate any advice on the potential cause of this issue or alternative solutions. If you’re able to provide a small code sample demonstrating the correct approach, it would be greatly appreciated. Thank you.

Hello. For context, is this about a networked game project? Does your implementation work in singleplayer?

As for how to implement what you’re after. Both root motion translation and rotation is consumed in CMC::PerformMovement. Rotation particularly is applied in this section:

// Apply Root Motion rotation after movement is complete. if( HasAnimRootMotion() ) { const FQuat OldActorRotationQuat = UpdatedComponent->GetComponentQuat(); const FQuat RootMotionRotationQuat = RootMotionParams.GetRootMotionTransform().GetRotation(); if( !RootMotionRotationQuat.IsIdentity() ) { const FQuat NewActorRotationQuat = RootMotionRotationQuat * OldActorRotationQuat; MoveUpdatedComponent(FVector::ZeroVector, NewActorRotationQuat, true); } }First of all, in your example code FMDRRootMotionSource_FaceTarget::PrepareRootMotion() you’re calculating an absolute rotation but the code above will implement it as a delta-rotation (already multiplied by delta-time), so I believe you need to change your approach there to set the difference to the target rotation.

Secondly, you can check whether NewActorRotationQuat actually is that rotation of facing the target. Put a breakpoint there, and use data breakpoints to find out what code is modifying the rotation next. It happens to be that my example in that article is character rotation since I found it tricky in the past too to find out what code was overriding my desired rotation. Hopefully that helps.

When you find more info like the callstack that triggers the data breakpoint, I can continue thinking along with you.