/// <summary>
 /// Finding and adding left arm
 /// </summary>
 /// <param name="transforms"></param>
 public void AddLeftArm(Transform[] transforms)
 {
     Transform[] results = JointNamings.GetTypeAndSide(JointNamings.JointObject.Arm, JointNamings.BodySide.Left, transforms);
     if (results.Length == 4)
     {
         if (!leftClavicle)
         {
             leftClavicle = results[0];
         }
         if (!leftUpperArm)
         {
             leftUpperArm = results[1];
         }
         if (!leftForearm)
         {
             leftForearm = results[2];
         }
         if (!leftHand)
         {
             leftHand = results[3];
         }
     }
     else if (results.Length == 3)
     {
         if (!leftUpperArm)
         {
             leftUpperArm = results[0];
         }
         if (!leftForearm)
         {
             leftForearm = results[1];
         }
         if (!leftHand)
         {
             leftHand = results[2];
         }
     }
     else
     {
         foreach (var res in results)
         {
             UnityEngine.Debug.Log(res);
         }
     }
 }
 /// <summary>
 /// Finding and adding right leg
 /// </summary>
 /// <param name="transforms"></param>
 public void AddRightLeg(Transform[] transforms)
 {
     Transform[] results = JointNamings.GetTypeAndSide(JointNamings.JointObject.Leg, JointNamings.BodySide.Right, transforms);
     if (results.Length == 3 || results.Length == 4)
     {
         if (rightThigh == null)
         {
             rightThigh = results[0];
         }
         if (rightCalf == null)
         {
             rightCalf = results[1];
         }
         if (rightFoot == null)
         {
             rightFoot = results[2];
         }
     }
 }
 /// <summary>
 /// Finding and adding right arm
 /// </summary>
 /// <param name="transforms"></param>
 public void AddRightArm(Transform[] transforms)
 {
     Transform[] results = JointNamings.GetTypeAndSide(JointNamings.JointObject.Arm, JointNamings.BodySide.Right, transforms);
     if (results.Length == 4)
     {
         if (!rightClavicle)
         {
             rightClavicle = results[0];
         }
         if (!rightUpperArm)
         {
             rightUpperArm = results[1];
         }
         if (!rightForearm)
         {
             rightForearm = results[2];
         }
         if (!rightHand)
         {
             rightHand = results[3];
         }
     }
 }
        /// <summary>
        /// Adds fingers to the references
        /// </summary>
        /// <returns>True if fingers were found</returns>
        public void AddFingers()
        {
            if (leftHand.childCount <= 0 || rightHand.childCount <= 0)
            {
                return;
            }
            var children = leftHand.GetDirectChildren();

            thumbLeft = JointNamings.GetBone(children, JointNamings.JointObject.Thumb, JointNamings.BodySide.Left);
            Transform[] results = JointNamings.GetTypeAndSide(JointNamings.JointObject.Fingers, JointNamings.BodySide.Left, children);
            if (results.Length == 4)
            {
                fingersLeft    = new Transform[4];
                fingersLeft[0] = results[0];
                fingersLeft[1] = results[1];
                fingersLeft[2] = results[2];
                fingersLeft[3] = results[3];
            }
            else if (results.Length == 1)
            {
                fingersLeft    = new Transform[1];
                fingersLeft[0] = results[0];
            }
            else if (leftHand && leftHand.childCount >= 5)
            {
                if (!thumbLeft)
                {
                    thumbLeft = leftHand.GetChild(0);
                }
                fingersLeft    = new Transform[4];
                fingersLeft[0] = leftHand.GetChild(1);
                fingersLeft[1] = leftHand.GetChild(2);
                fingersLeft[2] = leftHand.GetChild(3);
                fingersLeft[3] = leftHand.GetChild(4);
            }

            children   = rightHand.GetDirectChildren();
            thumbRight = JointNamings.GetBone(children, JointNamings.JointObject.Thumb, JointNamings.BodySide.Right);
            results    = JointNamings.GetTypeAndSide(JointNamings.JointObject.Fingers, JointNamings.BodySide.Right, rightHand.GetDirectChildren());
            if (results.Length == 4)
            {
                fingersRight    = new Transform[4];
                fingersRight[0] = results[0];
                fingersRight[1] = results[1];
                fingersRight[2] = results[2];
                fingersRight[3] = results[3];
            }
            else if (results.Length == 1)
            {
                fingersRight    = new Transform[1];
                fingersRight[0] = results[0];
            }
            else if (rightHand && rightHand.childCount >= 5)
            {
                if (!thumbRight)
                {
                    thumbRight = rightHand.GetChild(0);
                }
                fingersRight    = new Transform[4];
                fingersRight[0] = rightHand.GetChild(1);
                fingersRight[1] = rightHand.GetChild(2);
                fingersRight[2] = rightHand.GetChild(3);
                fingersRight[3] = rightHand.GetChild(4);
            }
        }
        /// <summary>
        /// Detects joints based on names and the hierarchy.
        /// </summary>
        /// <param name="root">The root of the biped humanoid</param>
        /// <param name="useFingers">bool wheter to include fingers or not</param>
        public void FindJointsByNaming(Transform root, bool useFingers)
        {
            Transform[] transforms = root.GetComponentsInChildren <Transform>();

            // Find limbs
            // Get left arm
            AddLeftArm(transforms);
            //// Get Right arm
            AddRightArm(transforms);
            // Get left leg
            AddLeftLeg(transforms);
            // Get right leg
            AddRightLeg(transforms);
            // Find fingers
            if (useFingers && !IsAllFingersSet())
            {
                AddFingers();
                if (!IsAllFingersSet())
                {
                    fingersLeft  = null;
                    fingersRight = null;
                }
            }
            // Find head bone
            if (!head)
            {
                head = JointNamings.GetBone(transforms, JointNamings.JointObject.Head);
            }
            // Find Neck
            if (!neck)
            {
                neck = JointNamings.GetBone(transforms, JointNamings.JointObject.Neck);
            }
            // Find Pelvis
            if (!pelvis)
            {
                pelvis = JointNamings.GetMatch(transforms, JointNamings.pelvisAlias);
            }
            //if pelvis not found, pelvis is common ancestor of the thighs
            if (!pelvis)
            {
                pelvis = rightThigh.CommonAncestorOf(leftThigh);
            }

            // Find spine
            Transform left, right;

            if (leftClavicle && rightClavicle)
            {
                left  = leftClavicle;
                right = rightClavicle;
            }
            else
            {
                left  = leftUpperArm;
                right = rightUpperArm;
            }
            if (left && right && pelvis)
            {
                Transform lastSpine = left.CommonAncestorOf(right);
                if (lastSpine)
                {
                    // if pelvis is not ancestor of last spine
                    if (!pelvis.IsAncestorOf(lastSpine))
                    {
                        // Set common ancestor to pelvis
                        pelvis = pelvis.CommonAncestorOf(lastSpine);
                    }
                    // Spine is all ancestors between last spine and pelvis
                    spine = GetAncestorsBetween(lastSpine, pelvis);
                    // Head is not set
                    if (!head)
                    {
                        for (int i = 0; i < lastSpine.childCount; i++)
                        {
                            Transform child = lastSpine.GetChild(i);
                            // all children of last spine that is not left and right
                            if (!child.ContainsChild(left) && !child.ContainsChild(right))
                            {
                                // if that object has a child, it is probably the head and that object the neck
                                if (child.childCount == 1)
                                {
                                    head = child.GetChild(0);
                                    neck = child;
                                    break;
                                }
                                // otherwise we set last spine as neck and its child as head
                                else
                                {
                                    head = child;
                                    neck = lastSpine;
                                    break;
                                }
                            }
                        }
                    }
                    else if (!neck)
                    {  // if Neck is not set but head is
                        if (lastSpine.IsAncestorOf(head))
                        {
                            neck = lastSpine;
                        }
                        else
                        {
                            for (int i = 0; i < lastSpine.childCount; i++)
                            {
                                Transform child = lastSpine.GetChild(i);

                                if (!child.ContainsChild(left) && !child.ContainsChild(right))
                                {
                                    neck = child;
                                }
                            }
                        }
                    }
                }
                if (neck && spine.Length > 0 && spine[spine.Length - 1] == neck)
                {
                    Array.Resize(ref spine, spine.Length - 1); // Can't have neck among the spines
                }
            }
        }