I have a model for a soccer robot which has a "leg" that can be used to shoot a ball. It is capable of shooting from a low and high position, allowing the ball to be shot through the air or plainly across the ground. I have achieved this initial behaviour using a rig with one IK controller and some constraints:

movement example

However, now I am slightly confused by the next step. This leg is connected to a plunger as well, which prevents the leg from clattering back and forth. It is connected to the leg via a pair of wheels on the inside of the leg, kind of like a slider, as shown here: plunger wheels This plunger will thus have to be able to extend and retract as the leg moves. I have tried to achieve this using a bone for the plunger which has a Copy Location constraint for just the Local Y axis (the direction along which the plunger should move). While it slides in and out as desired, there is a little issue: it always seems rather offset from where it should be for some reason:

gif shot incorrect

I can "fix" this by just moving it back with Offset enabled, but this seems like a rather dirty fix + I would like it to be quite accurate. Things that I have tried:

  • Apply location and scale of the plunger mesh, other meshes involved and the rig
  • Move the origin of the involved meshes and the armature
  • Try different constraints, such as Limit Distance. This generally leads to the same results
  • Rebuilding the rig from scratch

Screenshot of the constraints on the plunger bone:

plunger bone constraint

Attached is the .blend file with just the relevant objects included. I'm trying to understand why this is happening and/or there is a better alternative method available.


1 Answer 1


Well, the basic structure that you're trying to do here-- copying location, world->local-- is just not the right one for the problem you're trying to solve.

Let me start by being explicit about what your current constraint is doing: it is finding the world Y location of the head of foot_bone_low. This is a number. It is then applying that as local space Y translation to plunger_bone. This translation is not in the same axis as the world. It is not the same as halfway down the targeted bone. And there is no particular location on the bone that you would want to copy the location of, because that location changes as foot_bone_low rotates.

What you actually want is the location of the intersection of a plane perpendicular to foot_bone_low's Z axis, that roughly intersects the middle of rod2_low, and of the line described by plunger_bone's Y axis. Luckily, using other constraints, this is something we can get:

enter image description here

So first thing we're going to do is to make that plane that forms half of the intersection I was describing. We'll basically align it to rod2_low, then parent it bone relative to foot_bone_low. (When I did this on your file, other stuff mysteriously lost its transform, and I'm not sure why, but unparenting it with keep transform, then reparenting afterwards, solved the problem.)

We can make it wire display, disable it in renders, stick it in another collection-- anything we want to put that plane out of the way. It exists only for rigging purposes.

Now that we have that properly aligned plane, it's pretty simple to get the plunger to move with it. First, we'll delete the existing constraints on the plunger bone; next, we'll duplicate plunger and then parent the original to the duplicate (so we can still manipulate the plunger); finally, we'll give the duplicate a shrinkwrap constraint, targeting the plane. By setting the shrinkwrap constraint to project, in +-Y axes, our plunger will never change its rotation. Its Y axis will always lie in the same Y axis it had at rest. But as the plane rotates with rod_low, the plunger will draw back and forth.

Because we sandwiched this in as a new parent, we can still control the plunger manually as well. Recommended to transform lock all transforms of the duplicate, and all transforms but Y axis translation for the original plunger bone.

  • $\begingroup$ Wow, what a clever solution and great explanation of what I misunderstood about the Copy Location constraint. I have just tried it myself and it works beautifully. Thanks a lot for your help! $\endgroup$
    – Imetysaw
    Commented Jun 30, 2021 at 16:18
  • 2
    $\begingroup$ I second that 'Wow'. :) $\endgroup$
    – Robin Betts
    Commented Jun 30, 2021 at 16:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .