Download

IK effector bone space as a pin/var?

Is it possible to modify the effector space of an IK constraint in an AnimGraph at runtime?

Because IK constraints can have ugly “frame lag” when the target isn’t set in the space of a parent bone, it’s important sometimes to set that up. But often different animations require different IK constraints.

For example, in some animations, I might need the player’s right hand to have an IK target of his hip (for drawing a weapon). In others, I might need it to be his left hand (to hold a weapon anchored in the left hand). In still others, I might need the left hand to be anchored to a weapon held in the right hand. Every one of these potential uses requires a different set of IK constraints and a different set of weight values, at least in my current setup. What I’m wondering is if it’s possible to expose the “parent bone” of an IK constraint as a pin; that way, I can use a notify or some other variable adjustment method to say not only “this is the transform the left hand needs to reach”, but also “this is the bone that target is relative to”. Otherwise, I need a separate set of constraints for every single possible use case… or at least, for every possible use case where one-frame lag is unacceptable (which admittedly doesn’t cover EVERY use case, but it covers quite a few).

I think you complely missed the point on how IK is supposed to work.

You set a world location, the IK chain adjusts to point to that location.

Obviously you can change that location at runtime, or you would never be able to achieve anything similar.

Start by having a look at the content examples.
particularly since you are asking about weapons.

if you actually try what you’re describing, you’ll see that it doesn’t work like you think it does. World-space IK effector positions are fine when you are solving to an object in the world, because its position exists independently of the pose of the solver. It doesn’t work for solving to an effector which is itself driven by the pose of the skeleton you’re running the IK on, because poses are resolved in a single pass.

Say you want to use IK to keep a skeleton’s left hand touching a weapon mesh which is attached to a socket on its right hand. With the naive world-space approach, you sample the position of a socket on the weapon mesh, feed it to the AnimBP, and when the AnimBP calculates the pose that frame, it updates the position of the left hand to reach this target position… and then updates the position of the right hand, moving the mesh and the target socket. Now, next frame, it samples this new position for the socket, feeds it back in, and the left hand resolves to it again, at the same time as the right hand’s position once again updates.

You can see the issue here: when you sample a socket in world space you are always going to see that socket’s position last frame, not in the current frame. This creates a one-frame lag where the left hand “chases” the right hand through any animation data, because the left hand and right hand are resolved at the same time. If you instead use component space, you avoid some of the chasing (since you are sidestepping any world-space changes to the actor as it moves) but animated motion still produces problems.

The way to resolve this is to set your IK effector target up in the bone space, of the bone that ultimately drives the socket your effector is targeting. This forces the AnimBP to first resolve this bone’s position (to calculate its coordinate space) and THEN apply the IK solver to this updated position. This produces rock-solid, lock-step IK when using one bone to target another bone on the same skeleton.

This brings me back to my original issue, which is that in order to do this, you have to know the bone space you are targeting in advance. It’s fine as long as your left hand’s IK solver is always targeting a location which is relative to the right hand (you can change the position it targets, as long as it exists in that space) but it will only produce stable results IF the right hand is what moves it. So, say, you need the left hand to target a position relative to the right hand to hold a weapon, but then for a reload animation, you instead need the left hand to target a hip bone, to reach for a magazine. There’s no way, at least that I’ve found, to supply a bone name as a pin to change the space… so you need two IK solvers. One which takes in a right-hand-space location, and one which takes in a hip-space location, and then you adjust their weights. Otherwise, one of these will produce frame lag because there’s no guarantee the bone driving the target position will be resolved before the IK pose is resolved in the AnimBP’s pose update pass. But when you have a lot of potential IK interactions (left hand depends on right hand, left hand depends on hips, left hand depends on chest, right hand depends on left hand, right hand depends on upper back, right hand depends on hips, etc) that creates a huge mess of sequential IK solvers which are all at 0 blend weight except the relevant one.

I’m looking for a way to avoid this, specifically that doesn’t involve using naive world-space or component-space calculations which, as I explained above, produce frame lag when the solver’s position is updated after the animation.

EDIT: and before someone chimes in with it, no, changing tick groups for the mesh will not resolve this issue. If you consider it for a second you’ll see why; if you sample the position of the right hand after updating the pose, the pose won’t see the new sampled position until the next frame, but if you sample the position of the right hand before updating the pose, you’ll be updating the pose with a position sampled based on last frame’s data. The only way to produce stable results is to sample the position after resolving the pose of the driving bone but *before *resolving the pose of the IK chain, and the only way to sample data mid-stream in the pose update like that is to use a bone space IK constraint.

Tick group has absolutely noting to do with your incorrect diatribe on why it shouldn’t work. Which anyone can stop reading after the first 2 lines.

The content examples obviously show you otherwise.

that said,
obviously being able to expose the pin for the setting would be beneficial to someone for something - and I do believe it is already possible, since almost anything can be exposed.

Buddy, you can be smug if it makes you feel good about yourself, but this is a known issue with a known solution

https://forums.unrealengine.com/deve…hind-if-moving
https://forums.unrealengine.com/deve…-1-frame-later
https://forums.unrealengine.com/deve…hind-animation

https://forums.unrealengine.com/deve…hand-placement
https://answers.unrealengine.com/que…t-hand-ik.html
https://answers.unrealengine.com/que…4116/view.html
https://answers.unrealengine.com/que…sition-to.html

I could keep going but it’s getting boring. And you may notice how often “change the tick group” is (to your point, incorrectly) offered as a potential solution to this issue in these many threads and AnswerHub posts, which is why I decided to pre-empt it here.

You enjoy those toy Content Example tutorials, but when you try to actually implement pose-driven IK in a real game with real animations you will see that this is a common edge case which pops up when dealing with pose-driven socket rotation and translation.

Would you mind explaining how? If you could demonstrate how to expose this pin you might actually contribute to this thread.

Usually, every parameter on any control has an Eye option or an Expose checkbox. In the details panel. Normally to the right of the editor when selecting the node.

But again, if your solution is “change tick group” you are 100% doing things wrong.

If complex Full Body IK can work 100% glitch free with the default tick group, so can anything else.
The problem is much more likely to be that you don’t know how to use transforms to go from world to local (or whatever else) before passing the vector to the IK node / or solver. Since we do have at least 3 different solvers. Maybe more now with Control Rig.
off the top, FABRIK, CCDIK, and LegIK.

oh. And when you actually do change tick group, is normally when Physics alters the state of the animation so your solver goes fishing for wrong values. Some times.
if you track your gun with a socket location that becomes useless as the world position of the gun in world space is always accurate.

Brother, I’m fully aware changing tick group will not work. My whole point was that this is often suggested as a solution (even though it’s not a solution). I was trying to get out in front of that recommendation by saying that it won’t work (there are cases where it works, BTW, but those are cases where changing the tick group of the IK-using actor causes it to be processed after some other object in the world which it is IK-ing relative to, it’s not useful in the general case or with pose-driven animations)

The “space” settings don’t. What you’re saying is definitely true of most BP-exposed vars but AnimGraphs, like shader graphs and niagara graphs, use more restricted logic. The “space” settings on Component transform nodes cannot be exposed as pin, only effector locations. At least near as I have been able to figure out.

. I assure you, I know how to do transform conversion. If it was a transform conversion problem I’d get really clear issues like the hand stretching all the way across the map or being in the completely wrong direction. I can tell the difference between “the hand is resolving to a completely incorrect location” and “the hand is resolving to a one-frame-old target position because the update sequence is delayed until after the full pose is resolved”. You say “If complex Full Body IK can work 100% glitch free with the default tick group” but the issue is that Full Body IK only works glitch-free relative to WORLD controllers. You’re adjusting the body to suit other actors in the world (reaching for a ledge or holding on to a motorcycle or whatever nonsense example case you care to name). You’re not using the pose to drive other elements of the same pose. This, as I keep repeating over and over and over again (but you keep not reading it) involves special considerations, because you need to partially update the pose. You need to resolve the current frame transform of* one* bone and use that to drive the current frame transform of another bone within the same pose pass. Because the pose is resolved in a single pass, you cannot do this easily. The only way to do so is to use bone space transform drivers in your IK solver, precisely because using bone space transform drivers forces a pose to be partially resolved to calculate the space.

Maybe try placing your IK In a PostProcess animation blueprint.

That should ensure that the calculations of the current pose are up to date - before applying IK to it.
​physics are still happening after.
Usually you use the ppabp for aninmdynamic nodes.

Changing transform mode in an IK node does not magically pause the animation, get the accurate value, and moved the other object/bone/chain to it.

It’s just a different space value wich being LOCAL is more accurate (float precision can matter too if you use world locations).

Also, just adding to this, since I did have a look and indeed Effect Target is not something you can expose without stealing the node C++ and re-compiling it with the exposed pin.

You can always just use a blend by BoneControlSpace

you can get a switch from typing switch bone control space. and promote the selection pin to a var to get the drop down variable defined.
you can then move the pin to blend poses by Bone Control space. Right click and add pins to expose the various types.
Feed differently configured IK nodes into the different poses.
Pin the variable you created.
Set the default pose to the baseline animation.

And you worked around it in BP without having to compile a specific BP class with the exposed node.


Keep in mind that you are probably killing fast path by doing this.If the thunderbolt sign is gone from the blend you may be better off exposing the pin in C++