• Runtimes
  • Manually Move IK Constraint When Animation Is Playing (Unity)

Hello, I am trying to move a bone that has an IK Constraint tied to it during play, but it doesn't seem to work. I have noticed that by disabling all the animations the bone with the IK Constraint will move as intended. How can I achieve this?

My code is as follows (just like one of the runtime examples)

var bone = skeletonAnimation.Skeleton.FindBone("ArmRightIK2");
Vector3 mousePosition = Input.mousePosition;
Vector3 worldMousePosition = cam.ScreenToWorldPoint(mousePosition);
Vector3 skeletonSpacePoint = skeletonAnimation.transform.InverseTransformPoint(worldMousePosition);
skeletonSpacePoint.x *= skeletonAnimation.Skeleton.ScaleX;
skeletonSpacePoint.y *= skeletonAnimation.Skeleton.ScaleY;
    Related Discussions
    ...

    To move a bone with an IK constraint during an animation in Unity, you need to ensure that your changes are applied after the animation has been processed. This can be achieved by using the UpdateLocal callback provided by the SkeletonAnimation component. This ensures that your manual adjustments are applied after the animation has set the bone positions.

    Here is an example of how you can modify your code to use the UpdateLocal callback:

    using Spine.Unity;
    
    public class IKControl : MonoBehaviour {
        public SkeletonAnimation skeletonAnimation;
        public Camera cam;
    
        void Start() {
            skeletonAnimation.UpdateLocal += ApplyIK;
        }
    
        void ApplyIK(ISkeletonAnimation animatedSkeleton) {
            var bone = skeletonAnimation.Skeleton.FindBone("ArmRightIK2");
            Vector3 mousePosition = Input.mousePosition;
            Vector3 worldMousePosition = cam.ScreenToWorldPoint(mousePosition);
            Vector3 skeletonSpacePoint = skeletonAnimation.transform.InverseTransformPoint(worldMousePosition);
            skeletonSpacePoint.x *= skeletonAnimation.Skeleton.ScaleX;
            skeletonSpacePoint.y *= skeletonAnimation.Skeleton.ScaleY;
    
            bone.X = skeletonSpacePoint.x;
            bone.Y = skeletonSpacePoint.y;
        }
    }

    In this code, the ApplyIK method is called after the animation has been applied, ensuring that your manual bone adjustments are not overridden by the animation.

    Additionally, make sure that the IK constraint's mix value is set appropriately to allow the bone to follow the target position. You can adjust the mix value in the Spine editor or via code.

    skeletonAnimation.Skeleton.FindIkConstraint("ArmRightIK").Mix = 1.0f;

    This ensures that the IK constraint fully influences the bone's position.

    HeadMonitor I think you probably wrote that code by referring to SpineboyTargetController.cs, but I wonder why that the code you wrote is missing the last line bone.SetLocalPosition(skeletonSpacePoint);.
    Is it a simple copy and paste error, or did you not actually write it? This line does the same thing as the following part of the code proposed by Spinebot, so I think you should be able to copy and try the Spinebot code:

            bone.X = skeletonSpacePoint.x;
            bone.Y = skeletonSpacePoint.y;

      Misaki Thank you for the reply. I forgot to reply myself but the bot's reply was correct. Thanks!