See the attached file.
Bone "constraint" has a copy location constraint, with Influence taken from a driver.
The driver variable is a Transform Channel (local Y from the bone "control").
It doesn't matter if I use Driver type Scripted Expression or Averaged Value, as long as i use Transform Chanel as variable.
If I animate it (position of "control" at frame 20 in the file), and I use the arrow keys to move in time around that frame, there is a lag of one frame in the motion of bone "constraint" behind bone "control". This lag appears also when I render the animation. I made constant interpolation to make it visible better, but it appears also with linear interpolation.
The expected behaviour is that they should move at the same time.
When moving the bone "control" in the viewport (not animating), there is no such lag. However, a kind of lag appears when I move "control", then release it without confirming (so that it goes back to its initial position). The bone "constraint" stays at the non-confirmed positon until I do something (like moving the bone slightly, or just pressing G)
I found a workaround by using a scripted expression property, such as pose.bones["control"].location in this case. But the Transform Channel would be the more intuitive and straigtforward way for a user, and is supposed to work.
See the attached file.
- To Do
This is a known and ugly limitation with armatures. Blender thinks not that Bone A depends on Bone B. It thinks that "Armature" depends on "Armature" (itself) and solves this conflict by delayed updating. You will have to use different objects (for example two armatures) to achieve the desired result.
PS: Is this still on the todo list or already forgotten? ;-)
PPS: Scripted properties work in some cases if you are lucky that bone A is evaluated before bone B, if B depends on A. If B is a child of A then you should have no problem. If B is a sibling of A (both on same level or in independent chains, then it is more or less luck.
I'm really not sure how it is handled. It could change from version to version because it is not defined anywhere in which order the bones are evaluated.
* Parents are always first compared to a child.
* Constraint targets are always first.
* For drivers the source is evaluated first, but this will be seen as a cyclic dependency. That means: It should be fine as long you do the update manually, so that it is in time, while the dependency is satisfied, to ensure that the "source" is updated first. (add a source variable to the driver that should be actual source. Do the update directly inside the scripted expression)
It's still a hack, but it might work. Of course it would be much nicer to have a real solution as i already requested having then same issue.
Classic Object<->ObData dependency granularity problem. No easily solutions exist within the existing framework. Under certain limited circumstances, it may be possible to get situations where these problems aren't as obvious (namely, don't try to depend on anything on a bone or which gets update by a bone in that armature).