using UnityEngine; using System.Collections; using RootMotion; namespace RootMotion.Dynamics { /// /// Holds references to all Transforms required for a biped ragdoll. /// [System.Serializable] public struct BipedRagdollReferences { /// /// The root transform is the parent of all the biped's bones and should be located at ground level. /// public Transform root; /// /// The pelvis bone. /// public Transform hips; /// /// The middle spine bone. /// public Transform spine; /// /// The last spine bone. /// public Transform chest; /// /// The head. /// public Transform head; /// /// The first bone of the left leg. /// public Transform leftUpperLeg; /// /// The second bone of the left leg. /// public Transform leftLowerLeg; /// /// The third bone of the left leg. /// public Transform leftFoot; /// /// The first bone of the right leg. /// public Transform rightUpperLeg; /// /// The second bone of the right leg. /// public Transform rightLowerLeg; /// /// The third bone of the right leg. /// public Transform rightFoot; /// /// The first bone of the left arm. /// public Transform leftUpperArm; /// /// The second bone of the left arm. /// public Transform leftLowerArm; /// /// The third bone of the left arm. /// public Transform leftHand; /// /// The first bone of the right arm. /// public Transform rightUpperArm; /// /// The second bone of the right arm. /// public Transform rightLowerArm; /// /// The third bone of the right arm. /// public Transform rightHand; public bool IsValid(ref string msg) { if (root == null || hips == null || head == null || leftUpperArm == null || leftLowerArm == null || leftHand == null || rightUpperArm == null || rightLowerArm == null || rightHand == null || leftUpperLeg == null || leftLowerLeg == null || leftFoot == null || rightUpperLeg == null || rightLowerLeg == null || rightFoot == null ) { msg = "Invalid References, one or more Transforms missing."; return false; } var array = new Transform[15] { root, hips, head, leftUpperArm, leftLowerArm, leftHand, rightUpperArm, rightLowerArm, rightHand, leftUpperLeg, leftLowerLeg, leftFoot, rightUpperLeg, rightLowerLeg, rightFoot }; // Check if all are parented to the root for (int i = 1; i < array.Length; i++) { if (!IsChildRecursive(array[i], root)) { msg = "Invalid References, " + array[i].name + " is not in the Root's hierarchy."; return false; } } // Check for duplicates for (int i = 0; i < array.Length; i++) { for (int i2 = 0; i2 < array.Length; i2++) { if (i != i2 && array[i] == array[i2]) { msg = "Invalid References, " + array[i].name + " is represented more than once."; return false; } } } return true; } private bool IsChildRecursive(Transform t, Transform parent) { if (t.parent == parent) return true; if (t.parent != null) return IsChildRecursive(t.parent, parent); return false; } public bool IsEmpty(bool considerRoot) { if (considerRoot && root != null) return false; if (hips != null || head != null || spine != null || chest != null || leftUpperArm != null || leftLowerArm != null || leftHand != null || rightUpperArm != null || rightLowerArm != null || rightHand != null || leftUpperLeg != null || leftLowerLeg != null || leftFoot != null || rightUpperLeg != null || rightLowerLeg != null || rightFoot != null ) return false; return true; } /// /// Returns true if the References contain the specified Transform /// public bool Contains(Transform t, bool ignoreRoot = false) { if (!ignoreRoot && root == t) return true; if (hips == t) return true; if (spine == t) return true; if (chest == t) return true; if (leftUpperLeg == t) return true; if (leftLowerLeg == t) return true; if (leftFoot == t) return true; if (rightUpperLeg == t) return true; if (rightLowerLeg == t) return true; if (rightFoot == t) return true; if (leftUpperArm == t) return true; if (leftLowerArm == t) return true; if (leftHand == t) return true; if (rightUpperArm == t) return true; if (rightLowerArm == t) return true; if (rightHand == t) return true; if (head == t) return true; return false; } public Transform[] GetRagdollTransforms() { return new Transform[16] { hips, spine, chest, head, leftUpperArm, leftLowerArm, leftHand, rightUpperArm, rightLowerArm, rightHand, leftUpperLeg, leftLowerLeg, leftFoot, rightUpperLeg, rightLowerLeg, rightFoot }; } public static BipedRagdollReferences FromAvatar(Animator animator) { BipedRagdollReferences r = new BipedRagdollReferences(); if (!animator.isHuman) return r; r.root = animator.transform; r.hips = animator.GetBoneTransform(HumanBodyBones.Hips); r.spine = animator.GetBoneTransform(HumanBodyBones.Spine); r.chest = animator.GetBoneTransform(HumanBodyBones.Chest); r.head = animator.GetBoneTransform(HumanBodyBones.Head); r.leftUpperArm = animator.GetBoneTransform(HumanBodyBones.LeftUpperArm); r.leftLowerArm = animator.GetBoneTransform(HumanBodyBones.LeftLowerArm); r.leftHand = animator.GetBoneTransform(HumanBodyBones.LeftHand); r.rightUpperArm = animator.GetBoneTransform(HumanBodyBones.RightUpperArm); r.rightLowerArm = animator.GetBoneTransform(HumanBodyBones.RightLowerArm); r.rightHand = animator.GetBoneTransform(HumanBodyBones.RightHand); r.leftUpperLeg = animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg); r.leftLowerLeg = animator.GetBoneTransform(HumanBodyBones.LeftLowerLeg); r.leftFoot = animator.GetBoneTransform(HumanBodyBones.LeftFoot); r.rightUpperLeg = animator.GetBoneTransform(HumanBodyBones.RightUpperLeg); r.rightLowerLeg = animator.GetBoneTransform(HumanBodyBones.RightLowerLeg); r.rightFoot = animator.GetBoneTransform(HumanBodyBones.RightFoot); return r; } public static BipedRagdollReferences FromBipedReferences(BipedReferences biped) { BipedRagdollReferences r = new BipedRagdollReferences(); r.root = biped.root; r.hips = biped.pelvis; if (biped.spine != null && biped.spine.Length > 0) { r.spine = biped.spine[0]; if (biped.spine.Length > 1) r.chest = biped.spine[biped.spine.Length - 1]; } r.head = biped.head; r.leftUpperArm = biped.leftUpperArm; r.leftLowerArm = biped.leftForearm; r.leftHand = biped.leftHand; r.rightUpperArm = biped.rightUpperArm; r.rightLowerArm = biped.rightForearm; r.rightHand = biped.rightHand; r.leftUpperLeg = biped.leftThigh; r.leftLowerLeg = biped.leftCalf; r.leftFoot = biped.leftFoot; r.rightUpperLeg = biped.rightThigh; r.rightLowerLeg = biped.rightCalf; r.rightFoot = biped.rightFoot; return r; } } }