public void SetupFromHead()
    {
        feet = new List <BoneJoint>();
        List <BoneJoint> bodyJointsToVisit = new List <BoneJoint>();

        bodyJointsToVisit.Add(head);
        boneCount = 0;
        float     maxDistFromBodyJoint = 0f;
        float     maxDistFromHead      = 0f;
        BoneJoint latestBodyJoint      = null;

        while (bodyJointsToVisit.Count > 0)
        {
            BoneJoint currentJoint = bodyJointsToVisit[0];
            boneCount++;
            maxDistFromHead += currentJoint.distanceFromLastBone;
            currentJoint.maxDistanceFromHead = maxDistFromHead;
            latestBodyJoint      = currentJoint;
            maxDistFromBodyJoint = 0f;
            if (baseOfNeck == null)
            {
                if (currentJoint.nextJoints != null && currentJoint.nextJoints.Count >= 2)
                {
                    baseOfNeck = currentJoint;
                }
            }
            else if (currentJoint.nextJoints != null)
            {
                baseOfTail = currentJoint;
            }
            if (baseOfTail == null)
            {
                baseOfTail = currentJoint;
            }

            endOfTail = currentJoint;
            for (int i = 0; i < currentJoint.nextJoints.Count; i++)
            {
                BoneJoint nextJoint = currentJoint.nextJoints[i];
                if (nextJoint.isPartOfLeg())
                {
                    while (nextJoint != null)
                    {
                        boneCount++;
                        maxDistFromBodyJoint              += nextJoint.distanceFromLastBone;
                        nextJoint.maxDistanceFromHead      = maxDistFromHead + maxDistFromBodyJoint;
                        nextJoint.maxDistanceFromBodyJoint = maxDistFromBodyJoint;
                        nextJoint.closestBodyJoint         = latestBodyJoint;
                        if (nextJoint.nextJoints == null || nextJoint.nextJoints.Count == 0)
                        {
                            nextJoint.type = BoneJoint.BoneJointType.Foot;
                            feet.Add(nextJoint);
                            maxDistFromBodyJoint = 0f;
                            nextJoint            = null;
                        }
                        else
                        {
                            nextJoint = nextJoint.nextJoints[0];// No need to worry about other next joints as only a body joint can have multiple next joints
                        }
                    }
                }
                else
                {
                    bodyJointsToVisit.Add(nextJoint);
                }
            }
            bodyJointsToVisit.RemoveAt(0);
        }
        if (baseOfNeck == null)
        {
            baseOfNeck = head;
        }

        for (int i = 0; i < feet.Count; i++)
        {
            BoneJoint currentBonejoint = feet[i];
            float     dist             = 0;
            while (currentBonejoint.previousJoint != null && currentBonejoint.isPartOfLeg())
            {
                currentBonejoint.attachedFoot     = feet[i];
                currentBonejoint.distanceFromFoot = dist;
                currentBonejoint = currentBonejoint.previousJoint;
                dist            += currentBonejoint.distanceFromLastBone;
            }
            if (currentBonejoint != null && currentBonejoint.isPartOfBody())
            {
                currentBonejoint.type = BoneJoint.BoneJointType.Hip;
            }
        }
    }
    void FeedForward(Joint previous, Joint currentJoint)
    {
        if (previous.m_boneJoint == null || currentJoint.m_boneJoint == null)
        {
            return;
        }
        Vector2 previousJointPos = previous.transform.position;
        Vector2 currentJointPos  = currentJoint.transform.position;

        Vector2 targetPos = GetPosLocked(previousJointPos, currentJointPos, currentJoint.m_boneJoint.distanceFromLastBone, false);

        if (currentJoint.m_boneJoint.isPartOfLeg()) //is either a legjoint
        {
            if (currentJoint.m_boneJoint.nextJoints != null)
            {
                Vector3 footPos = currentJoint.m_boneJoint.attachedFoot.transform.position;

                float   maxDistFromFoot    = currentJoint.m_boneJoint.distanceFromFoot;
                float   maxDist            = currentJoint.m_boneJoint.maxDistanceFromBodyJoint + maxDistFromFoot;
                float   rotationToAddCurve = m_legCurve.Evaluate(maxDistFromFoot / maxDist);
                float   footToBodyAngle    = Vector2.Angle(Vector2.right, (Vector2)(currentJoint.m_boneJoint.closestBodyJoint.transform.position - footPos));
                Vector2 toAdd  = new Vector2(0, maxDistFromFoot / maxDist);
                Vector2 curved = (Quaternion.Euler(0, 0, footToBodyAngle * rotationToAddCurve) * toAdd) * m_legCurveStrength;
                curved += currentJointPos;

                Vector3 lockedPos = GetPosLocked(previousJointPos, curved, currentJoint.m_boneJoint.distanceFromLastBone, false);
                targetPos = GetPosLocked(footPos, lockedPos, currentJoint.m_boneJoint.distanceFromFoot, true);
            }
            else //if is a foot
            {
                targetPos = currentJointPos;
            }
        }
        else
        {
            if (currentJoint.m_boneJoint.type == BoneJoint.BoneJointType.Hip)
            {
                for (int i = 0; i < currentJoint.m_boneJoint.nextJoints.Count; i++)
                {
                    BoneJoint nextJoint = currentJoint.m_boneJoint.nextJoints[i];
                    if (nextJoint.isPartOfLeg())
                    {
                        Vector2 lockedTo    = nextJoint.attachedFoot.transform.position;
                        Vector2 jointMaxPos = GetPosLocked(lockedTo, nextJoint.transform.position, nextJoint.distanceFromFoot, true);
                        jointMaxPos = GetPosLocked(jointMaxPos, currentJointPos, nextJoint.distanceFromLastBone, false); //where the joint should be

                        targetPos = GetPosLocked(previousJointPos, jointMaxPos, currentJoint.m_boneJoint.distanceFromLastBone, false);
                        targetPos = GetPosLocked(lockedTo, targetPos, nextJoint.distanceFromFoot + nextJoint.distanceFromLastBone, true);
                        break;
                    }
                }
            }
            else
            {
                BoneJoint nextHip     = currentJoint.m_boneJoint;
                float     distFromHip = 0;
                int       i           = 0;
                while (nextHip.type != BoneJoint.BoneJointType.Hip && nextHip.nextJoints.Count > 0)
                {
                    nextHip      = nextHip.nextJoints[0];
                    distFromHip += nextHip.distanceFromLastBone;
                }
                Vector2 jointMaxPos = GetPosLocked(nextHip.transform.position, currentJointPos, distFromHip, true);
                targetPos = GetPosLocked(previousJointPos, jointMaxPos, currentJoint.m_boneJoint.distanceFromLastBone, false);
            }
        }
        currentJoint.transform.position = targetPos;//Vector2.MoveTowards(currentJoint.transform.position, targetPos, m_boneJointsLerpSpeed * Time.deltaTime);
        UpdatePosToNeighbours(currentJoint, previous);
    }