suanLoBeach I initially thought your goal could be easily achieved with physics constraints and bone followers, so I considered recommending existing examples. However, realizing there might not be a direct reference, I created a simple example instead.
First, I made a flower using physics constraints, where its swaying motion is animated by rotating the bones. Additionally, I created an animation that integrates IK constraints in Unity, similar to the aim animation in Spineboy:
The Spine project file can be downloaded here:
Next, I used Bone Follower
to make a Box Collider 2D follow the bones around the middle of the flower (flower_3
). When the mouse enters the Collider's range, the IK
animation is applied on track 1, causing the IK target bone to follow the mouse position. This interaction inhibits the flower’s movement when the mouse hovers over it. Once the mouse exits the Collider’s range, the animation on track 1 mixes out, and the IK bones return to their original position. (For the animation on track 0, the IK target bone is constrained by a transform constraint to match the position of the flower_2
bone, ensuring they return to their original position.)
InteractingWithFlowe.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Spine;
using Spine.Unity;
public class InteractingWithFlower : MonoBehaviour
{
public SkeletonAnimation skeletonAnimation;
public Spine.AnimationState spineAnimationState;
[SpineBone(dataField: "skeletonAnimation")]
public string boneName;
public Camera cam;
Bone bone;
void OnValidate () {
if (skeletonAnimation == null) skeletonAnimation = GetComponent<SkeletonAnimation>();
}
void Start () {
spineAnimationState = skeletonAnimation.AnimationState;
spineAnimationState.SetAnimation(0, "animation", true);
bone = skeletonAnimation.Skeleton.FindBone(boneName);
}
void OnMouseOver () {
Debug.Log("OnMouseOver");
if(spineAnimationState.GetCurrent(1) == null){
spineAnimationState.SetAnimation(1, "IK", false);
}
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.SetLocalPosition(skeletonSpacePoint);
skeletonAnimation.Skeleton.UpdateWorldTransform(Skeleton.Physics.Update);
}
void OnMouseExit() {
Debug.Log("OnMouseExit");
spineAnimationState.SetEmptyAnimation(1,0);
}
}
I’ve written a lot, but there are many different approaches to achieving the same result. For example, in this case, I enabled the IK constraint by playing an animation on an upper track. However, since the IK Mix value can be changed directly via script, that approach could work as well.
I’m not sure if my method is the best fit for what you want to achieve, but I hope it helps you get a better idea of what can be done with Spine and the spine-unity runtime.