• Runtimes
  • [XNA] Moving a bone during animation

Related Discussions
...

Hi guys,

I've tried doing this before and gave up - now I'm back with renewed effort to get it working. However, after much searching I'm still coming up blank.

I have a death animation for my characters. What I want to do is set the World position of a bone while all other bones animate as usual.

The bone I want to move will have its location stored when the animation begins, and then have gravity and other physics applied to it to basically dismember it.

Unfortunately, right now all that happens is it keeps its transform from the animation and flies all over the place.

Here's what I'm doing:

if (!IsBoneDetached)
{
   AnimState.Update(_et);
   AnimState.Apply(Skeleton);
   Skeleton.UpdateWorldTransform();
}
else
{
   AnimState.Update(_et);
   AnimState.Apply(Skeleton);
}

// And then further on in the code.. if the limb is detached..

detachedBone.Data.InheritRotation = false;
trajectory.Y += Global.Gravity * gameTime;
location += trajectory * gameTime;
rotation += rotationSpeed * gameTime;

bone.X = location.X;
bone.Y = location.Y;
bone.Rotation = rotation;

detachedBone.UpdateWorldTransform();
skeleton.UpdateWorldTransform();

The rotation seems to work perfectly fine, but I can't seem to get the bone to ignore the position set by the skeletons animation and only use the position I give it. I've even tried removing the bonedata for detachedBone.

So, just to clarify, all bones should animate as keyframed, except the detachedBone which I want to set its WorldX and WorldY position myself.

Is this possible and if so, any help would be very much appreciated!
Regards,
James


Is this really not possible or nobody knows how?

It should work. Eg, set both bone.X and bone.Y to -100 and you should see that you are moving the detached bone. Note that the bone's local position (bone.X and bone.Y in your code) is relative to it's parent bone. You can use bone.parent.worldToLocal(location.X, location.Y, localX, localY) to convert from skeleton world coordinates to bone local coordinates. Keep in mind that doing this conversion uses the world transform, so you'll need to UpdateWorldTransform before using worldToLocal and then again after changing the detached bone's local position. However, instead of calling skeleton.UpdateWorldTransform twice, you can call bone.UpdateWorldTransform after changing the detached bone's local position, since there is no reason to update all the bones when you've only changed the detached bone.

Thankyou, I'll give it a try later.

I had managed to get the bones position moved, but it was still being affected by the parent bones position and rotation, which I didn't want. I think I'm understanding it better now, so thanks - this is like the last piece of the puzzle for my game 🙂


Just to let you know, I managed to get this working correctly. I had missed the transform to local positions, so simply adding in the bone.parent.worldToLocal() transform worked a treat! Looks awesome too! 8)

Many thanks!