• Unity
  • Spine Unity - Making the arm follow the mouse

I am trying to get the arm in the spine animation to follow the mouse so it looks good when I shoot, here is an example of what I want it to do but using spine: I have been looking through the code trying to find a specific method to develop a way to do this but have yet figured out a way!

Spine(http://esotericsoftware.com/) is an animation tool that I am using in unity for animations for a game that my team and I are developing. I am currently on the player controller and have been stuck on this part of the project for a week or so. I have developed a way to create a fire point using the bonefoller.cs script within spine-unity runtime, so it shoots from a specific position(Bone) that I set it to. Just need a way to let the arm from the shoulder to follow the exact position of the mouse so it works seamlessly. If there is anyone out there that has a background in using spine with unity that would be awesome to get some help from you! If there is also some documentation furthering my knowledge on how to do so that would also be accepted 🙂 Thank-you in advance if you help me!!! 😃 This was a copy that I asked on stack overflow but didn't realize there was a form on spine! 🙂)))

Related Discussions
...
  • Изменено

Hello! If you are using Spine PRO (which is required for being able to define IK Constraints in Spine Editor), then the animator/rigger needs to setup an IK Constraint.

Then at runtime, all you need to do is to control the IK Target bone position. The Spine-Unity runtime provides a method that allows you to set a bone position according to a given Unity world position:

using UnityEngine;
using Spine.Unity;

public class BoneControllerSample : MonoBehaviour {

   [SpineBone]
   public string boneName;
   Spine.Bone bone;
   public Vector3 targetPosition;

   void Start () {
      SkeletonAnimation skeletonAnimation = GetComponent<SkeletonAnimation>();
      this.bone = skeletonAnimation.Skeleton.FindBone(boneName);
      skeletonAnimation.UpdateLocal += SkeletonAnimation_UpdateLocal;
   }

   void SkeletonAnimation_UpdateLocal (ISkeletonAnimation animated) {
      var localPositon = transform.InverseTransformPoint(targetPosition);
      bone.SetPosition(localPositon);
   }

}

If you are using Spine Essential, you can't set up an IK Constraint. So you'd need to do the math yourself. If that's the case, having a simpler skeleton (like in the video you linked) will make things easier.

using UnityEngine;
using Spine.Unity;

public class BoneControllerSample : MonoBehaviour {

   [SpineBone]
   public string boneName;
   Spine.Bone bone;
   public Vector3 targetPosition;

   void Start () {
      SkeletonAnimation skeletonAnimation = GetComponent<SkeletonAnimation>();
      this.bone = skeletonAnimation.Skeleton.FindBone(boneName);
      skeletonAnimation.UpdateWorld += SkeletonAnimation_UpdateWorld;
   }

   void SkeletonAnimation_UpdateWorld (ISkeletonAnimation animated) {
      var bonePosition = bone.GetWorldPosition(this.transform);
      var direction = targetPosition - bonePosition;
      float rotation = DirectionToRotation(direction, this.transform);
      float parentRotation = bone.parent.WorldRotationX;
      bone.RotateWorld(rotation - parentRotation);
   }

   static float DirectionToRotation (Vector3 direction, Transform transform) {
      var localDirection = transform.InverseTransformDirection(direction);
      return Mathf.Atan2(localDirection.y, localDirection.x) * Mathf.Rad2Deg;
   }

}

here is my code:

public string boneName = "back aim ik";
   Spine.Bone bone;
   public Vector3 targetPosition;



   /// <summary>
   /// This method is used to initialize anyhting at the start of the game..
   /// </summary>
   void Start ()
   {
      rigidbody2D = GetComponent<Rigidbody2D> ();
      //Removes gun to test pick up mechanic
      SetAnimation("idle",true);
      //code for arm movement
      this.bone = skeletonAnimation.Skeleton.FindBone(boneName);
      skeletonAnimation.UpdateLocal += SkeletonAnimation_UpdateLocal;
   }

   void SkeletonAnimation_UpdateLocal (ISkeletonAnimation animated)
   {
      var localPositon = transform.InverseTransformPoint(Input.mousePosition);
      bone.SetPosition(localPositon);
   }

my animator guy has created an IK constraint to the arm to make it all move and I am pointing it to the position of the mouse... but for some reason, it's not working... you have any solutions? Im getting this null reference exception:

NullReferenceException: Object reference not set to an instance of an object
Spine.Unity.SkeletonExtensions.SetPosition (Spine.Bone bone, Vector3 position) (at Assets/spine-unity/SkeletonExtensions.cs:109)
PlayerController.SkeletonAnimation_UpdateLocal (ISkeletonAnimation animated) (at Assets/Scripts/PlayerController.cs:76)
Spine.Unity.SkeletonAnimation.Update (Single deltaTime) (at Assets/spine-unity/SkeletonAnimation.cs:180)
Spine.Unity.SkeletonAnimation.Update () (at Assets/spine-unity/SkeletonAnimation.cs:167)

It's a NullReferenceException.
You probably had the wrong bone name.

If the bone name is inspector-assigned, we recommend using the [SpineBone] attribute in code so the inspector shows a list of bones you can select from, instead of needing you to manually type the name correctly.

[SpineBone]
public string boneName;

Alright ill try it over the weekend and get back to you on how it works out!!! 🙂