Unity Inverse Kinematics 2D

IK관련 코드


using UnityEngine;

public class IKManager : MonoBehaviour
{
    public Joint root;
    public Joint end;

    public GameObject target;

    public float threshold = 0.05f;

    public float rate = 5f;

    public int step = 20;
    float CalculateSlope(Joint joint)
    {
        float delthTheta = 0.01f;
        float distacne1 = GetDistance(end.transform.position, target.transform.position);
        
        joint.Rotate(delthTheta);

        float distance2 = GetDistance(end.transform.position, target.transform.position);
        
        joint.Rotate(-delthTheta);

        return (distance2 - distacne1) / delthTheta;
    }

    private void Update()
    {
        for (int i = 0; i < step; ++i)
        {
            if (GetDistance(end.transform.position, target.transform.position) > threshold)
            {
                Joint current = root;
                while (current != null)
                {
                    float slope = CalculateSlope(current);
                    current.Rotate(-slope * rate);
                    current = current.GetChild();
                }
      
            }
        }
    }

    public float GetDistance(Vector3 p1, Vector3 p2)
    {
        return Vector3.Distance(p1, p2);
    }
}
using UnityEngine;

public class Joint : MonoBehaviour
{
    public Joint child;

    public Joint GetChild()
    {
        return child;
    }

    public void Rotate(float angle)
    {
        transform.Rotate(Vector3.up, angle);
    }
}