/// <summary> /// Automatically detects biped bones. Returns true if a valid biped has been referenced. /// </summary> public static bool AutoDetectReferences(ref BipedReferences references, Transform root, AutoDetectParams autoDetectParams) { if (references == null) { references = new BipedReferences(); } references.root = root; // If that failed try the Animator var animator = root.GetComponent <Animator>(); if (animator != null && animator.isHuman) { AssignHumanoidReferences(ref references, animator, autoDetectParams); return(true); // Assume humanoids are always valid } // Try with naming and hierarchy first DetectReferencesByNaming(ref references, root, autoDetectParams); Warning.logged = false; if (!references.isFilled) { Warning.Log("BipedReferences contains one or more missing Transforms.", root, true); return(false); } if (!CheckSetupError(references, true)) { return(false); } CheckSetupWarning(references, true); return(true); }
// Check if spine is properly set up private static bool CheckSpineError(BipedReferences references, bool log) { if (references.spine.Length == 0) { return(true); } for (int i = 0; i < references.spine.Length; i++) { if (references.spine[i] == null) { if (log) { Warning.Log("BipedReferences spine bone at index " + i + " is null.", references.root, true); } return(false); } } Transform duplicate = (Transform)Hierarchy.ContainsDuplicate(references.spine); if (duplicate != null) { if (log) { Warning.Log(duplicate.name + " is represented multiple times in BipedReferences spine.", references.spine[0], true); } return(false); } if (!Hierarchy.HierarchyIsValid(references.spine)) { if (log) { Warning.Log("BipedReferences spine hierarchy is invalid. Bone transforms in the spine do not belong to the same ancestry. Please make sure the bones are parented to each other.", references.spine[0], true); } return(false); } for (int i = 0; i < references.spine.Length; i++) { bool matchesParentPosition = false; if (i == 0 && references.spine[i].position == references.pelvis.position) { matchesParentPosition = true; } if (i != 0 && references.spine.Length > 1 && references.spine[i].position == references.spine[i - 1].position) { matchesParentPosition = true; } if (matchesParentPosition) { if (log) { Warning.Log("Biped's spine bone nr " + i + " position is the same as it's parent spine/pelvis bone's position. Please remove this bone from the spine.", references.spine[i], true); } return(false); } } return(true); }
// Check if the limb is properly set up private static bool CheckLimbError(Transform bone1, Transform bone2, Transform bone3, bool log) { if (bone1 == null) { if (log) { Warning.Log("Bone 1 of a BipedReferences limb is null.", bone2, true); } return(false); } if (bone2 == null) { if (log) { Warning.Log("Bone 2 of a BipedReferences limb is null.", bone3, true); } return(false); } if (bone3 == null) { if (log) { Warning.Log("Bone 3 of a BipedReferences limb is null.", bone1, true); } return(false); } if (bone2.position == bone1.position) { if (log) { Warning.Log("Second bone's position equals first bone's position in the biped's limb.", bone2, true); } return(false); } if (bone3.position == bone2.position) { if (log) { Warning.Log("Third bone's position equals second bone's position in the biped's limb.", bone3, true); } return(false); } Transform duplicate = (Transform)Hierarchy.ContainsDuplicate(new Transform[3] { bone1, bone2, bone3 }); if (duplicate != null) { if (log) { Warning.Log(duplicate.name + " is represented multiple times in the same BipedReferences limb.", bone1, true); } return(false); } if (!Hierarchy.HierarchyIsValid(new Transform[3] { bone1, bone2, bone3 })) { if (log) { Warning.Log( "BipedReferences limb hierarchy is invalid. Bone transforms in a limb do not belong to the same ancestry. Please make sure the bones are parented to each other. " + "Bones: " + bone1.name + ", " + bone2.name + ", " + bone3.name, bone1, true); } return(false); } return(true); }
/* * Check if the limb is properly set up * */ private static bool CheckLimb(Transform bone1, Transform bone2, Transform bone3, bool log) { if (bone2.position == bone1.position) { if (log) { Warning.Log("Second bone's position equals first bone's position in the biped's limb.", bone2, true); } return(false); } if (bone3.position == bone2.position) { if (log) { Warning.Log("Third bone's position equals second bone's position in the biped's limb.", bone3, true); } return(false); } Transform duplicate = (Transform)Hierarchy.ContainsDuplicate(new Transform[3] { bone1, bone2, bone3 }); if (duplicate != null) { if (log) { Warning.Log(duplicate.name + " is represented multiple times in the same BipedReferences limb.", bone1, true); } return(false); } if (!Hierarchy.HierarchyIsValid(new Transform[3] { bone1, bone2, bone3 })) { if (log) { Warning.Log( "BipedReferences limb hierarchy is invalid. Bone transforms in a limb do not belong to the same ancestry. Please make sure the bones are parented to each other. " + "Bones: " + bone1.name + ", " + bone2.name + ", " + bone3.name, bone1, true); } return(false); } Vector3 cross = Vector3.Cross(bone2.position - bone1.position, bone3.position - bone1.position); if (cross == Vector3.zero) { if (log) { Warning.Log( "BipedReferences limb is completely stretched out in the initial pose. IK solver can not calculate the default bend plane for the limb. " + "Please make sure you character's limbs are at least slightly bent in the initial pose. " + "First bone: " + bone1.name + ", second bone: " + bone2.name + ".", bone1, true); } return(false); } return(true); }