Sprite GetCorrectSprite(BoneJoint joint)
 {
     if (joint.isPartOfBody())
     {
         if (joint.previousJoint == null)
         {
             return(m_headSprite);
         }
         else
         {
             return(m_bodySprite);
         }
     }
     else
     {
         if (joint.nextJoints == null || joint.nextJoints.Count == 0)
         {
             return(m_feetSprite);
         }
         else
         {
             return(m_legSprite);
         }
     }
 }
    public GameObject CreateSkeletonGameObject(Skeleton s, System.Random random)
    {
        GameObject creature = Instantiate(m_creaturePrefab);

        creature.GetComponent <Creature>().m_skeleton = s;
        List <BoneJoint> jointsToVisit = new List <BoneJoint>();

        jointsToVisit.Add(s.head);
        GameObject lastJointGO           = creature;
        float      bodyLineRendererScale = Mathf.Lerp(m_bodyLineRendererScaleMinMax.x, m_bodyLineRendererScaleMinMax.y, (float)random.NextDouble());
        float      legsLineRendererScale = Mathf.Lerp(m_legsLineRendererScaleMinMax.x, m_legsLineRendererScaleMinMax.y, (float)random.NextDouble());

        while (jointsToVisit.Count > 0)
        {
            BoneJoint currentJoint = jointsToVisit[0];
            if (currentJoint.previousJoint != null)
            {
                lastJointGO = currentJoint.previousJoint.gameObject;
            }
            GameObject currentJointGO = Instantiate(m_jointPrefab);
            currentJointGO.transform.parent     = creature.transform;// lastJointGO.transform;
            currentJointGO.transform.localScale = currentJoint.scale;
            currentJointGO.transform.position   = lastJointGO.transform.position;

            Vector2 pos = Utility.PolarToCartesian(currentJoint.distanceFromLastBone, currentJoint.angleFromLastBone);
            currentJointGO.transform.position += new Vector3(pos.x, pos.y, 0);
            currentJointGO.GetComponent <SpriteRenderer>().material.color = currentJoint.color;
            if (m_useSprites)
            {
                Sprite correctSprite = GetCorrectSprite(currentJoint);
                if (correctSprite != null)
                {
                    currentJointGO.GetComponent <SpriteRenderer>().sprite = correctSprite;
                }
            }
            Joint joint = currentJointGO.AddComponent <Joint>();
            joint.m_boneJoint = currentJoint;

            LineRenderer lr = currentJointGO.GetComponent <LineRenderer>();
            lr.SetPosition(0, currentJointGO.transform.position);
            lr.startColor = currentJoint.color;
            lr.startWidth = currentJoint.scale.x * (currentJoint.isPartOfBody() ? bodyLineRendererScale : legsLineRendererScale);
            lr.SetPosition(1, lastJointGO.transform.position);
            if (currentJoint.previousJoint != null)
            {
                lr.endWidth = currentJoint.previousJoint.scale.x * (currentJoint.previousJoint.isPartOfBody() ? bodyLineRendererScale : legsLineRendererScale);
                lr.endColor = currentJoint.previousJoint.color;
            }
            currentJoint.gameObject = currentJointGO;
            currentJoint.transform  = currentJointGO.transform;
            jointsToVisit.RemoveAt(0);
            if (currentJoint.nextJoints != null)
            {
                jointsToVisit.AddRange(currentJoint.nextJoints);
            }
        }
        return(creature);
    }
    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;
            }
        }
    }