Distance Matching Locomotion : Giving it a shot!

**7/24/19 - **Testing implementation with Kubold Animations set

**6/30/2019 **- Extra video. At last added proper turn in place !

Why bother?
You can achieve a perfect result of character and movement synchronization using rootmotion animations & root motion controllers, but there’s several issues with that:

First of all, with root motion the movement is baked into the animation and cannot be adjusted for gameplay reasons, if you want your character to drag more than usual because of ice on the ground you can’t, while using charactermovement component ground friction could do just that for the capsule movement.
Another issue is replication, root motion is driven by baked movement into the animation, while classic capsule based movement (CharacterMovementComponent) is driven by predictable, efficiently replicated kinematic equations.
Last but not least, artistic control, handling camera for kinematic driven capsule movement works extremely well and can be handcrafted to extreme details without unwanted movement getting in the way.


**6/18/2019 **- Displaying Distance to predicted stop by solving the differential equation of kinematic motion with braking deceleration force

Showing some debug distance on the video below - As you notice i’ve some trouble with clothing and skin cache compute !
Some transitions are made ‘instant’, there’s barely any smoothing happening here, only the distance matching:


**2/20/2019 **- Hello, decided to look into distance matching locomotion over the last two weeks and here are the results.

The Paragon presentation from Laurent Delayen was trully an inspiration!

3 Likes

Awesome!! any chance to share the code or some tips?? I’m very interested in this!

Oh i’m open to talk about what i’ve done and how to set it up on your own. As far as code sharing not so much, still spent a couple serious hours on this.
Yet, Epic might distribute their own solution as mentionned a couple times on stream anyway.

I think the hardest part is to solve the first order derivative equation of the characterMovement component, to predict where the pawn will stop/Pivot.
Highschool math right there, otherwise it’s rather straight forward:

  1. Compute Distance to point
  2. Search the animation file’ distance curve for proper time to be at
  3. Play the animation on single frame mode and provide the time you found as input
  4. Repeat

Thank you for sharing this. I watched epic’s original stream when it first came out. This has been on the todo list ever since. Need to get serious about this soon.

Hi! How to get value from animation curve at specified time? I know, that I need to implement this method through c ++

Not sure it’s answering your question properly, but in C++ , given a UAnimSequence pointer, you can access the curve data by calling GetCurveData()

Then accessing the actual float curves by acessing… FloatCurves , then iterate trough curves while checking their displayname and access the curve you want:




void UMagicAnimInstance::Tralala(UAnimSequence* Sequence)
{

FRawCurveTracks CurvesOfAnim = Sequence->GetCurveData();
TArray<FFloatCurve> Curves = CurvesOfAnim.FloatCurves;

for (int i=0; i<Curves.Num(); i++)
    {
        if (Curves*.Name.DisplayName == "DistanceCurve")
        {
          // Do Magic with Curves*.FloatCurve.Keys].Value
        }
    }

}



1 Like

After two month of collecting information about distance matching, it finally works. Of course it’s not finish yet, but i have most of walking movement:

  • start walk forward + orientation warping
  • stop walk forward left or right foot + orientation warping
  • strafe walk left start
  • strafe walk left stop left foot (right foot soon)
  • strafe walk right start
  • strafe walk right stop right foot (left foot soon)
  • start walk backward
  • stop walk backward left foot (right foot soon)

Very cool. It looks almost exactly like the talk demo.

I have made changes from the last time.
Instead of using UAnimSequence, now i looking throught UBlendSpace for start and stop animations except stop backward, which looks very weird and buggy, because in this direction you have two values -180/180, so i let it be in UAnimSequence and blend all animations by Cardinal Direction from Enum Values.

The reason of using UBlendSpace it saves time for setting all animations up.

It has full stop walking animation depends on foot position now.

Video below:

Any one worth their salt will address the twitching rear blendspace by isolating it into its own blend space 2d.

however, the content examples did not use blend for movement, they implemented the speed warping node which scaled down the animation via ik bone manipulation.

Similar with the actual rotation, they had a node that specifically turned the character spine and matched the pelvis.

I think you should branch the system and offer both ways if you still have the code… the blendspace way is very common and a great thing to have. The anim sequence is used occasionally - mostly by those who won’t rely on the blendspace not even for speed.

Thank you for your feedback. I know what you are talking about, its orientation warping.
I know about speed warping too.
Yes, i still have the code.

That’s really nice , the trickiest part for me was figuring out how the kinematic equation was implemented in in the charactermovement component.

What i’m doing is solving the first order equation, but there must be some details i overlooked as my predictions still range from 0.001 to (sometimes) 2.0 Unreal Units, which is actually already enough, for me at least. I guess you could get more precise but i haven’t spent more time on this as i doubt it was really worth it.

Showing some debug distance on the video below - As you notice i’ve some trouble with clothing and skin cache compute !
Some transitions are made ‘instant’, there’s barely any smoothing happening here, only the distance matching:

I’m curious, how it will look like with paragon character, because of you :smiley:
I see, you are more advanced and more experieced programmer that me.

One question:
When are you starting to compute stop position, when character was moving and is not accelerating?

Exactly, once character stop accelerating i predict/compute the stop position once and then iterate computation of the distance to this stop point to drive the animation.
Same process with pivot and start animations, like in the Laurent Delayen presentation.

Idk. I prefer the unreal dummy to the paragon characters. Especially considering how many shaders they compute when you shove them in a level :stuck_out_tongue:

Out of curiosity and for edification purposes…

Is the distance matching also active during acceleration?

Would determining when the stop occurs not just be a matter of material friction, gravity, and current speed/inertia?

I don’t particularly care about what stop anim plays when, I’m just curious on whether or not those systems already account for different gravity and terrain materials or not…

it’s overall a really cool idea since the math behind it isn’t super sophisticated and it can shift your results greatly depending on gameplay conditions.

Try stopping on ice, right?

Do you mean this presentation? :slight_smile:
https://archives.nucl.ai/secure/UO6Ux-YYTWG7dti-x-nPhA/1560888807/files/nuclai16/bringing-a-hero-from-paragon-to-life-with-ue4.pdf

Yep, I was anyway. Lots of interesting concepts that were brought about by that, even if it’s not quite perfect.

The jump pre land state is also kinda interesting as it can easily be piggie backed to do land rolls if falling for a certain time length vs just a jump. Sort of. Capsule movement needs to be pushed forward by a custom curve or parameter for that to happen since in the standard blueprint the character movement component zeros out the movement when landing…

You have huge knowledge. Thanks for tips.

I remember implementing this after Laurent’s livestream. From memory, after following the CharacterMovement code path, the main issue was that braking deceleration varied over time based on the capsule’s current velocity. With my limited understanding of integrals, this made it tricky to solve for final distance (integrating with a variable that depended on its own integral). Someone with better math understanding might have seen the solution/workaround as obvious, but I had to search random math forums to find a similar problem to copy the approach of (and still didn’t really understand).

Eventually I got a solution mostly working, however it suffered from inaccuracy via framerate changes, with differences of up to 5UU depending on what framerate I tested at. That could be hacked around, but I remember being pretty frustrated capsule braking wasn’t calculated using constants.

Exactly this one, think there’s also a video of the talk somewhere.