Root motion preserve character velocity

I’m trying to use root motion to animate my character during attacks and things aren’t going well:

Apparently, the character movement component overrides the character’s velocity, except on the Z axis, where it keeps the velocity to allow for gravity to have an effect. Unfortunately I need my character to be able to play animations with root motion…

a) during jumps
b) while decelerating from movement

in both cases currently, my character just comes to a stop immediately. What I need is for the root motion to just be added to the velocity instead of overriding it, but I just can’t make it work. I was thinking to disable root motion on my character completely and put my own root motion code in place. So I tried making my own CharacterMovementComponent, but nothing I try works the way I need it to.

I tried overriding CharacterMovementComponent::ConstrainAnimRootMotionVelocity: if I return RootMotionVelocity + CurrentVelocity, the character just accelerates to an insane speed -> not what I want. If I try to disable root motion by just returning CurrentVelocity, yes, root motion is ignored but now the character cannot accelerate or deccelerate during animations with root motion, he will just keep walking at the speed he had when the animation started.

Is there any way to make this work?

1 Like

Same here. Help is appreciated,

Thanks in advance,

Couple potential things to try based on workarounds we had to do, if you haven’t tried these already:

  • lower gravity when jumping

GetCharacterMovement()->GravityScale = ?;

  • increase air control

GetCharacterMovement()->AirControl = ?;
GetCharacterMovement()->AirControlBoostMultiplier = ?;
GetCharacterMovement()->AirControlBoostVelocityThreshold = ?;

  • reduce braking and ground friction

GetCharacterMovement()->BrakingFriction = ? ;
GetCharacterMovement()->BrakingFrictionFactor = ? ;
GetCharacterMovement()->FallingLateralFriction = ? ;
GetCharacterMovement()->GroundFriction = ? ;

Wasn’t aware of this so glad your post made me look it up. :cool:…ion/index.html

FVector UCharacterMovementComponent::ConstrainAnimRootMotionVelocity(const FVector& RootMotionVelocity, const FVector& CurrentVelocity) const
    FVector Result = RootMotionVelocity;

    // Do not override Velocity.Z if in falling physics, we want to keep the effect of gravity.
    if (IsFalling())
        Result.Z = CurrentVelocity.Z;

    return Result;

Velocity is being set to Result every frame within UCharacterMovementComponent::ApplyRootMotionToVelocity if you’re using root motion. Changing the first line of the ConstrainAnimRootMotionVelocity function to

FVector Result = RootMotionVelocity + CurrentVelocity;

is causing your velocity to skyrocket since you’re always adding RootMotionVelocity to your velocity nearly every tick. What you need to do is add RootMotionVelocity to what your velocity would normally be without root motion. If you want to be able to add your root motion Z speed to your velocity while falling you have to do the same to this line as well:

Result.Z = CurrentVelocity.Z;

1 Like

Set the movement mode on the character movement to flying. This negates any gravity and your root motion Z value will work. Then when the animation is completed, set the movement mode to walking. This is the only solution.