- 수정됨
Make arm aim at IK Point
I apologize for the seeming doublepost but I realized that I may have been getting off topic in my last post which was specific to moving an IK target using the joystick.
I am trying to figure out how to get bones in Unity to look at an IK target. Currently the bone either does nothing when I apply code to it, or if I set it's override to the IK target, itself, it bends and skews either in the wrong way, or teleports to the IK target position (or its inverse). So either things are totally warped, inverted and warped, or teleported to the either the IK target or it's inverse position. I've been trying lots of different things and nothing has been working very well, or having no apparent affect at all.
Currently I'm trying this code from this post:
Spine Unity - Making the arm follow the mouse
This doesn't actually seem to make my animation do anything aside from preventing my shooting arm from transitioning from it's idle state into the shooting state. Anyone else run into that issue trying to implement this/their own methods? How did you fix it?
And lastly, my current code looks like this:
[SpineBone]
public string _boneName;
Spine.Bone bone;
public Vector3 targetPos;
public Transform IK_Target;
SkeletonAnimation skeletonAnimation;
Weapon_Select rotater;
public float Tester;
private void Start()
{
rotater = GetComponentInParent<Weapon_Select>();
SkeletonAnimation skeletonAnimation = GetComponent<SkeletonAnimation>();
this.bone = skeletonAnimation.Skeleton.FindBone(_boneName);
skeletonAnimation.UpdateLocal += SkeletonAnimation_UpdateLocal;
}
void SkeletonAnimation_UpdateLocal(ISkeletonAnimation animated)
{
var bonePos = bone.GetWorldPosition(this.transform);
var direction = targetPos - bonePos;
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;
}
private void LateUpdate()
{
skeletonAnimation.UpdateLocal += SkeletonAnimation_UpdateLocal;
}
Any help is appreciated!
You can have a look at Spineboy's setup and code in the Spine Examples/Getting Started/4 Object Oriented Sample
scene that is included in the spine-unity package. Here Spineboy aims and fires his gun at the mouse cursor position.
Harald wroteYou can have a look at Spineboy's setup and code in the
Spine Examples/Getting Started/4 Object Oriented Sample
scene that is included in the spine-unity package. Here Spineboy aims and fires his gun at the mouse cursor position.
Gosh somehow I missed that looking through the examples folder. Thank you for your help! That example looks a lot like what I'm going for . Now to hunt around here for how to change weights for IK points via script haha.
You're welcome, glad it helped!
Regarding IK constraint weights: it's called Mix
:
var constraint = skeletonAnimation.Skeleton.FindIkConstraint("aim");
constraint.Mix = 0.5f;
Harald wroteYou're welcome, glad it helped!
Regarding IK constraint weights: it's called
Mix
:var constraint = skeletonAnimation.Skeleton.FindIkConstraint("aim"); constraint.Mix = 0.5f;
Thank you !
Okay.......
So I literally copied and pasted the code from the example that was mentioned above into a script and that has the exact same issues as before. Could a setting at export cause this? Otherwise, could this be a possible bug that anyone else has reported?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Spine.Unity;
namespace Spine.Unity.Examples
{
public class IKConstraints : MonoBehaviour
{
public SkeletonAnimation skeletonAnimation;
[SpineBone(dataField: "skeletonAnimation")]
public string boneName;
public new Camera camera;
Bone bone;
void OnValidate()
{
if (skeletonAnimation == null) skeletonAnimation = GetComponent<SkeletonAnimation>();
}
void Start()
{
bone = skeletonAnimation.Skeleton.FindBone(boneName);
}
void Update()
{
var mousePosition = Input.mousePosition;
var worldMousePosition = camera.ScreenToWorldPoint(mousePosition);
var skeletonSpacePoint = skeletonAnimation.transform.InverseTransformPoint(worldMousePosition);
skeletonSpacePoint.x *= skeletonAnimation.Skeleton.ScaleX;
skeletonSpacePoint.y *= skeletonAnimation.Skeleton.ScaleY;
bone.SetLocalPosition(skeletonSpacePoint);
}
}
}
Sorry to hear that.
Does your setup work correctly in Spine? E.g. when you move your aim target
bone around while in Animation mode, does everything move as desired? Perhaps you find any difference to the IK setup in the Spineboy example project that comes with Spine?
Harald wroteSorry to hear that.
Does your setup work correctly in Spine? E.g. when you move your
aim target
bone around while in Animation mode, does everything move as desired? Perhaps you find any difference to the IK setup in the Spineboy example project that comes with Spine?
In the spine program things move correctly. Perhaps I have misunderstood what I am assigning in Unity? I'm attaching this script to the arm I want to move. Should it be attached to the IK target itself, with me adding a separate script to the bones to adjust the weights?
You do not want to move (translate) an arm, you want to move the IK target to the mouse position. The IK rig will adjust your arm bones accordingly, if things are setup correctly.
You should thus move the IK target position with the script. You can also try to move the IK target Transform
around in the Unity Editor and see if it works. Then move it using the mouse as a second step.
The IK Target weight adjustment is made via the skeletonAnimation
reference as described above, so you could attach your component there.