AddImpulse and LaunchCharacter fail on X and Y only with Root Motion

This bug touches multiple BP nodes such as Add Impulse Character Movement Component; Add Impulse (Mesh); and Launch Character.

If the animations and state machine are configured to NOT use root motion then these impulse nodes will cause the Character to move on X, Y, and Z as expected and as documented.

In the failure described here the impulse will fail on X and Y but succeed on Z.

Two conditions are needed for failure:

  1. Character’s Animation Blueprint is configured to use Root Motion from Everything in Anim Preview Editor | Edit Defaults.

  2. One or more States in the AnimGraph Default state machine must use an animation sequence (or blend space) that has ‘Enable Root Motion’ set to true (checked).

I believe that a root motion character should respond to impulses in 3D - currently this can happen only straight up.

When using Add Impulse (Mesh) on a bone such as ‘spine_03’ when physics are enabled - extreme vertical impulses will cause the character to fly up as expected. But huge horizontal impulses on X & Y will not shift the Character Movement Component - the character behaves as if the feet are anchored in concrete as the body slams sideways.

I have a sample project available for download for the asking.

Regards,

1 Like

Sample project

This problem still exists on 4.8 Preview 4. Hoping this issue report will get some Epic love before long!

According to void UCharacterMovementComponent::PerformMovement(float DeltaSeconds) this is not a bug :

const FVector RootMotionVelocity = RootMotionParams.RootMotionTransform.GetTranslation() / DeltaSeconds;
// Do not override Velocity.Z if in falling physics, we want to keep the effect of gravity.
Velocity = FVector(RootMotionVelocity.X, RootMotionVelocity.Y, (MovementMode == MOVE_Falling ? Velocity.Z : RootMotionVelocity.Z));

RootMotion always override Velocity on X and Y axis, launching a character will be handled on Z axis only (and that seems legit).

I solved this by overriding virtual void StartNewPhysics(float deltaTime, int32 Iterations) override; in my own CharacterMovementComponent and restoring the X/Y velocity before UE uses it, it’s quite ugly but it works well for me.

Thanks for taking the time to make this reply and for the suggested solution. Can’t say that I agree with the design decision here.

It seems very strange to intentionally turn AddImpulse to a NOP for RootMotion. While the integrity of the animation can not be guaranteed if external forces are allowed to impact the RootMotion sequence - it is likely that that impact is triggered by something from an unpredictable angle we won’t want to animate for. On hits / overlaps I’m blending in and out of ragdoll so this is a period in which things will get sloppy anyways.

I do want an opportunity to influence character navigation on a hit and AddImpulse seems like the best way to achieve it from BP.

A case can also be made against turning Add Impulse (Mesh) into a NOP. For example the character might be driving the capsule X & Y without interruption but a projectile hit to the head or shoulder should still be something the dev can easily represent. Enable physics on affected joints, apply an impulse. And that impulse is ignored unless vertical?

If I have reason to call AddImpulse then I probably want it to actually do something when called. I can omit the call if it isn’t needed or isn’t something I can manage neatly.

I’ll submit this on the forum as a feature request.

Feature request

Cø - are you available for a bit of conversation on this approach and your CharacterMovementComponent?

If i understand you, you want to push your Character to its side while playing a RootMotioned animation.

You could do it by storing a local space offset position in your character when it has been hit and then apply part of this offset during its tick, it should only take a few BP to achieve it (my own C++ version is doing it on Translation and Rotation with replication in less than 20 lines).

That isn’t exactly what I’m attempting. The standard collision capsule radius is sized to cover the pelvis and torso but the character limbs often extend outside this area. So I want to attach additional collision objects to lower legs and lower arms. I get overlap notifications when these pass thru static meshes like walls. Ideally these would be blocked collisions but that isn’t working so I’m looking for ways to keep limbs from passing thru walls and actors.

When an arm overlap with a wall is detected, I enable a physics blend on the upper body. I’d like to add an impulse to the arm to try and keep it out of the wall. Based on the size of the impulse (collision velocity) the arm, the upper torso, or the entire character should kick back to minimize penetration while the root motion animation is in progress.

So at the moment I’m thinking a genuine impulse on a bone should deflect the limb from the wall penetration and cause a modification of character navigation when large enough. The character might partially or completely crumple into the wall, shouldn’t penetrate it, and might rebound slightly in extreme velocity situations.

To implement your CharacterMovementComponent override - was it necessary to create a private build of the engine or can it be handled as C++ class / library add-in? If you’ll consider doing a bit of tutoring or custom class work as a small contract we should talk offline. I’m also on the forums and can be PM’d there.

I would have try the arm/upperbody movement using FABRIK or Bone Transform in the AnimGrap.

I didn’t understand your need and i don’t think you need to override the MovementComponent, it is only useful to move the RootComponent (and so the whole character), not part of your skeleton.

You can override the CharacterMovementComponent using very basic C++ project, there are few tutorial showing how to do this for beginners.

Sorry to necromance this… but can you give a bit more detail on how you changed the character movement component? I’m very poor at c++, but I need to add a way to keep x and y velocity and if possible to add a way to manipulate root motion translation and rotation before it is applied to the capsule. Thank you.


Hello I need some your help.
When character move to somewhere using root motion, This character hit the other AI or Monster. How did you push the other character?..
Did You set character actor relocated? or
Did you use AddImpuse in custom CharacterMovementComponent?..

Actually I think AddImpulse is better than relocating actor. Because when character block wall.
Could you tell me how to solve this problem?..
How to push the character to character?

Hi Minnow,

he didn’t face this in our game, we used avoidance to prevent AI from hitting the player while moving but as our AI were nearly all agressives they always change state and enter combat before colliding with the player so i didn’t need a solution for this.

We implemented a custom position offset interpolation in our AI MovementComponent when we needed to move them outide NavMesh or away from opening door, this could do the trick aswell.

1 Like