Help Interpolating Between Vectors in Character Blueprint

Hi,

Really quick background: I’m basically trying to achieve something like this - Procedural IK Leg Animation

**So far, I’ve managed to get to this point. **
(Please ignore the broken knees and orange guy at this point, I’m only focused on animating the IK foot targets right now and working out the kinks before applying this to a real model.)

Also, here’s my current EventGraph for the character.

What I’m basically doing is performing foot raycasts and using them to drive two sets of vector variables: Rest Position and Current Position. The Rest variables are anchored to the character root. Meanwhile the Current Position is used directly as the IK Target for the feet (each foot has its own). These Current Position variables are driven by the Rest ones but remain in place until a distance threshold is reached between the Rest and Current vectors.

Once that distance threshold is reached, ideally the Current Position would interpolate toward the Rest vector position with some kind of curve or arc in the Z axis. If that happened, then the character would plant his foot, keep it there until the Rest position was a certain distance away then smoothly raise it, interpolate it toward the updated Rest position, lower it back into place, and basically take a step.

However, the setup I have currently just causes them to pop into their new position so the character basically just ‘shuffle pops’ around.

What I’m trying to figure out and could use help with is how to correctly set up the smooth interpolation between Current and Rest positions once the threshold is reached. I’ve tried fiddling with VInterp To but don’t know if that’s what I should be doing or how to make it work in this context. Any help would be really appreciated.

Cheers!

VInterp doesn’t seem to be working the way I’d expect.

Here’s a screenshot of how I was using VInterp (might be wrong?)

And here’s the result (only the right foot)

I have the Interp Speed set to 50 in this video, but no speed setting ever really smooths it out. At a low setting (1 or 2) it basically never ‘steps’ forward and instead jitters in place, and at higher settings like 50+ it basically just pops like it did before.

I’m not sure if I’m just completely misusing this, however, and could use help figuring out what I should be doing differently. In my EventGraph, the only ‘original’ bit of data is coming from the Effector Hit Location output from the IK Foot Rest Raycast function. From there it directly sets the Rest Position R vector variable.

That should all be fine, but it’s after that point that I’m unsure if I’m going about this correctly. Right now I then hop down to the distance threshold Branch, and check if the Current and Rest vectors are 80 units away. If they are, it updates the Current vector to change positions to the Rest vector - effectively ‘popping’ it into place. When I try driving the Current Position R vector with the VInterp, it still pops (either big pops like the video above or little jittery ones without much movement).

I’m not sure if I need a third variable in there somewhere too, like a Target variable, so the Target would pop into place (invisibly behind the scenes) while the Current variable (the one actually driving the foot IK) would then interpolate over toward the Target? Also, I assume there needs to be some kind of additional distance threshold, so the foot sticks in place (maybe for half the distance, which would be 40 in this example) before trying to interpolate?

I’ve tried a number of different things but have lost a sense of direction about the best way to handle this :frowning:

Yes, a VInterp is exactly what you need, at least in terms of interpolating between 2 vectors. Creating the “arc”, on the other hand, is entirely different problem. What is the issue you’re having with the Vinterp?

I’m personally a sucker for doing this kind of interpolation manually, by using a float to keep track of “time” of the interpolation. In the tick you increase the float with delta time until it reaches its max.

Essentially this as long as Time is less than EndTime:

Time += DeltaTime;

Interpolation = Time / EndTime; // 0.0-1.0

Then in the tick you do something similar to this:

Direction = EndPosition-StartPosition;

InterpolatedPosition = StartPosition + Direction*Interpolation; // ground plane

InterpolatedPosition.Z = InterpolatedPosition.Z + GetCurveValue(Interpolation); // height

You can create a custom curve asset in the content browser to use for that last part, or do a mathematical arc.

You can probably use the LERP functions to achieve similar things.

Yes, I think you need a third variable. I’m just guessing, but I think the problem is that you are setting the VInterp “Return Value” output as the the next frame’s “Current” input, so it never has a chance to actually interpolate from one vector to another. If that makes sense.

Although I would try what Denny is suggesting below, if you can grasp it. He seems to know what he’s talking about. That stuff is way over my head though lol =)

Thanks for the detailed answer! I’m still a bit unclear on the implementation, though (you’re much more advanced than me).

Here’s what I attempted to set up based on how I understood your post.

But I know there are things in here that I’m doing wrong (it still pops). A few things I was especially uncertain about:

  • I obviously need to use time to interpolate positions (movement over time), but I’m not using time as a trigger for each step, since I want ‘sticky’ feet (if the character rotates in place, one foot will likely stick while the other will move accordingly).
  • With that in mind, I wasn’t sure where you were pulling or generating the EndTime variable from?
  • Actually, I’m guessing the the way I set up the Time related variables isn’t going to work, but I’m not sure how to correct them. Still trying to wrap my head around this.
  • I added new variables for Time, Interpolation (a float), Direction (vector), and I assume the Interpolated Position is the one I had formerly labeled as “Current Position” (the one actually driving the IK foot that gets rendered). Is this in line with what you were thinking or am I misunderstanding?
  • Even before getting to the Z Curve aspect of lifting the foot, I wasn’t sure how you were creating the InterpolatedPosition variable by multiplying the Direction Vector with the Interpolation Float? Did you intend for these variables to be used in an Interp function or am I on the wrong track?

I’m working in BP and trying to keep up, but if you’re able to elaborate or tell me where I’m going wrong, I’d really appreciate it :slight_smile:

Thanks again!

EDIT: In my screenshot the white Execution line isn’t connected to Set the Time variable (on the far left), but this was just a goof from when I was testing other stuff. I did have it connected when I ran through the first few iterations, so the slip up with the screenshot isn’t the root of the issue I’m having (sadly).

I recorded a Youtube video with a working example that you can reference from. This example has a constant bounce. You would of course have to control when it happens.

Youtube Video

Note in the video, where I have InterpolationTime / InterpolationDuration. This value can be used with an easing function, if you want to have easein/easeout in your character steps. So add it directly after the division for that.

Oh my gosh, I can’t thank you enough! That video explanation and walkthrough of your setup gave me everything I needed (and taught me some tricks I can use on other things in the future)!

Here’s a brief video of the result of using your interpolation logic (only focusing on the feet and ignoring the broken knees).

I added a conditional branch that also incorporates my old distance threshold, so that the Interpolation Time is only allowed to advance if the foot is a certain distance from it’s Rest/End location. This gives me the sticky feet I wanted plus a nice smooth animation once that threshold is reached.

Here’s a image of the EventGraph I have in place now.

From this point I can easily continue iterating on this (adding things like alternating steps and so on).

Again, thank you so much for the detailed explanation, I really appreciate the time you took to help :slight_smile:

I’m glad I could help. Tweaking the duration and maybe adding some easing to those steps and it will look really good!

By the way, AnswerHub is kinda iffy, so if you reply to a post that is marked as answered. It will become unanswered.

Cheers!