You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			318 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C#
		
	
		
		
			
		
	
	
			318 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C#
		
	
| 
								 
											1 year ago
										 
									 | 
							
								using UnityEngine;
							 | 
						||
| 
								 | 
							
								using System.Collections;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace RootMotion.FinalIK {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// <summary>
							 | 
						||
| 
								 | 
							
									/// %IK system for standard biped characters that is designed to replicate and enhance the behaviour of the Unity's built-in character %IK setup.
							 | 
						||
| 
								 | 
							
									/// </summary>
							 | 
						||
| 
								 | 
							
									[HelpURL("http://www.root-motion.com/finalikdox/html/page4.html")]
							 | 
						||
| 
								 | 
							
									[AddComponentMenu("Scripts/RootMotion.FinalIK/IK/Biped IK")]
							 | 
						||
| 
								 | 
							
									public class BipedIK : SolverManager {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Open the User Manual URL
							 | 
						||
| 
								 | 
							
										[ContextMenu("User Manual")]
							 | 
						||
| 
								 | 
							
										private void OpenUserManual() {
							 | 
						||
| 
								 | 
							
											Application.OpenURL("http://www.root-motion.com/finalikdox/html/page4.html");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										// Open the Script Reference URL
							 | 
						||
| 
								 | 
							
										[ContextMenu("Scrpt Reference")]
							 | 
						||
| 
								 | 
							
										private void OpenScriptReference() {
							 | 
						||
| 
								 | 
							
											Application.OpenURL("http://www.root-motion.com/finalikdox/html/class_root_motion_1_1_final_i_k_1_1_biped_i_k.html");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										// Link to the Final IK Google Group
							 | 
						||
| 
								 | 
							
										[ContextMenu("Support Group")]
							 | 
						||
| 
								 | 
							
										void SupportGroup() {
							 | 
						||
| 
								 | 
							
											Application.OpenURL("https://groups.google.com/forum/#!forum/final-ik");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										// Link to the Final IK Asset Store thread in the Unity Community
							 | 
						||
| 
								 | 
							
										[ContextMenu("Asset Store Thread")]
							 | 
						||
| 
								 | 
							
										void ASThread() {
							 | 
						||
| 
								 | 
							
											Application.OpenURL("http://forum.unity3d.com/threads/final-ik-full-body-ik-aim-look-at-fabrik-ccd-ik-1-0-released.222685/");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										#region Main Interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// References to character bones.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										public BipedReferences references = new BipedReferences();
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// The %IK solvers.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										public BipedIKSolvers solvers = new BipedIKSolvers();
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Gets the %IK position weight.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='goal'>
							 | 
						||
| 
								 | 
							
										/// %IK Goal.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public float GetIKPositionWeight(AvatarIKGoal goal) {
							 | 
						||
| 
								 | 
							
											return GetGoalIK(goal).GetIKPositionWeight();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Gets the %IK rotation weight.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='goal'>
							 | 
						||
| 
								 | 
							
										/// IK Goal.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public float GetIKRotationWeight(AvatarIKGoal goal) {
							 | 
						||
| 
								 | 
							
											return GetGoalIK(goal).GetIKRotationWeight();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Sets the %IK position weight.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='goal'>
							 | 
						||
| 
								 | 
							
										/// %IK Goal.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										/// <param name='weight'>
							 | 
						||
| 
								 | 
							
										/// Weight.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public void SetIKPositionWeight(AvatarIKGoal goal, float weight) {
							 | 
						||
| 
								 | 
							
											GetGoalIK(goal).SetIKPositionWeight(weight);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Sets the %IK rotation weight.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='goal'>
							 | 
						||
| 
								 | 
							
										/// %IK Goal.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										/// <param name='weight'>
							 | 
						||
| 
								 | 
							
										/// Weight.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public void SetIKRotationWeight(AvatarIKGoal goal, float weight) {
							 | 
						||
| 
								 | 
							
											GetGoalIK(goal).SetIKRotationWeight(weight);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Sets the %IK position.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='goal'>
							 | 
						||
| 
								 | 
							
										/// %IK Goal.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										/// <param name='IKPosition'>
							 | 
						||
| 
								 | 
							
										/// Position.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public void SetIKPosition(AvatarIKGoal goal, Vector3 IKPosition) {
							 | 
						||
| 
								 | 
							
											GetGoalIK(goal).SetIKPosition(IKPosition);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Sets the %IK rotation.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='goal'>
							 | 
						||
| 
								 | 
							
										/// %IK Goal.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										/// <param name='IKRotation'>
							 | 
						||
| 
								 | 
							
										/// Rotation.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public void SetIKRotation(AvatarIKGoal goal, Quaternion IKRotation) {
							 | 
						||
| 
								 | 
							
											GetGoalIK(goal).SetIKRotation(IKRotation);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Gets the %IK position.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='goal'>
							 | 
						||
| 
								 | 
							
										/// %IK Goal.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public Vector3 GetIKPosition(AvatarIKGoal goal) {
							 | 
						||
| 
								 | 
							
											return GetGoalIK(goal).GetIKPosition();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Gets the %IK rotation.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='goal'>
							 | 
						||
| 
								 | 
							
										/// %IK Goal.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public Quaternion GetIKRotation(AvatarIKGoal goal) {
							 | 
						||
| 
								 | 
							
											return GetGoalIK(goal).GetIKRotation();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Sets the look at weight.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='weight'>
							 | 
						||
| 
								 | 
							
										/// Master Weight.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										/// <param name='bodyWeight'>
							 | 
						||
| 
								 | 
							
										/// Body weight.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										/// <param name='headWeight'>
							 | 
						||
| 
								 | 
							
										/// Head weight.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										/// <param name='eyesWeight'>
							 | 
						||
| 
								 | 
							
										/// Eyes weight.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										/// <param name='clampWeight'>
							 | 
						||
| 
								 | 
							
										/// Clamp weight for body and head.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										/// <param name='clampWeightEyes'>
							 | 
						||
| 
								 | 
							
										/// Clamp weight for eyes.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public void SetLookAtWeight(float weight, float bodyWeight , float headWeight, float eyesWeight, float clampWeight, float clampWeightHead, float clampWeightEyes) {
							 | 
						||
| 
								 | 
							
											solvers.lookAt.SetLookAtWeight(weight, bodyWeight, headWeight, eyesWeight, clampWeight, clampWeightHead, clampWeightEyes);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Sets the look at target.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='lookAtPosition'>
							 | 
						||
| 
								 | 
							
										/// Look at position.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public void SetLookAtPosition(Vector3 lookAtPosition) {
							 | 
						||
| 
								 | 
							
											solvers.lookAt.SetIKPosition(lookAtPosition);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Sets the spine %IK position.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='spinePosition'>
							 | 
						||
| 
								 | 
							
										/// Spine %IK position.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public void SetSpinePosition(Vector3 spinePosition) {
							 | 
						||
| 
								 | 
							
											solvers.spine.SetIKPosition(spinePosition);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Sets the spine weight.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <param name='weight'>
							 | 
						||
| 
								 | 
							
										/// Weight.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public void SetSpineWeight(float weight) {
							 | 
						||
| 
								 | 
							
											solvers.spine.SetIKPositionWeight(weight);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Gets the limb solver for the %IK Goal.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										/// <returns>
							 | 
						||
| 
								 | 
							
										/// The solver.
							 | 
						||
| 
								 | 
							
										/// </returns>
							 | 
						||
| 
								 | 
							
										/// <param name='goal'>
							 | 
						||
| 
								 | 
							
										/// %IK Goal.
							 | 
						||
| 
								 | 
							
										/// </param>
							 | 
						||
| 
								 | 
							
										public IKSolverLimb GetGoalIK(AvatarIKGoal goal) {
							 | 
						||
| 
								 | 
							
											switch(goal) {
							 | 
						||
| 
								 | 
							
											case AvatarIKGoal.LeftFoot: return solvers.leftFoot;
							 | 
						||
| 
								 | 
							
											case AvatarIKGoal.RightFoot: return solvers.rightFoot;
							 | 
						||
| 
								 | 
							
											case AvatarIKGoal.LeftHand: return solvers.leftHand;
							 | 
						||
| 
								 | 
							
											case AvatarIKGoal.RightHand: return solvers.rightHand;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return null;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// (Re)Initiates the biped IK solvers.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										public void InitiateBipedIK() {
							 | 
						||
| 
								 | 
							
											InitiateSolver();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Updating BipedIK
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										public void UpdateBipedIK() {
							 | 
						||
| 
								 | 
							
											UpdateSolver();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 
							 | 
						||
| 
								 | 
							
										 * Set default solver values.
							 | 
						||
| 
								 | 
							
										 * */
							 | 
						||
| 
								 | 
							
										public void SetToDefaults() {
							 | 
						||
| 
								 | 
							
											// Limbs
							 | 
						||
| 
								 | 
							
											foreach (IKSolverLimb limb in solvers.limbs) {
							 | 
						||
| 
								 | 
							
												limb.SetIKPositionWeight(0f);
							 | 
						||
| 
								 | 
							
												limb.SetIKRotationWeight(0f);
							 | 
						||
| 
								 | 
							
												limb.bendModifier = IKSolverLimb.BendModifier.Animation;
							 | 
						||
| 
								 | 
							
												limb.bendModifierWeight = 1f;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											solvers.leftHand.maintainRotationWeight = 0f;
							 | 
						||
| 
								 | 
							
											solvers.rightHand.maintainRotationWeight = 0f;
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											// Spine
							 | 
						||
| 
								 | 
							
											solvers.spine.SetIKPositionWeight(0f);
							 | 
						||
| 
								 | 
							
											solvers.spine.tolerance = 0f;
							 | 
						||
| 
								 | 
							
											solvers.spine.maxIterations = 2;
							 | 
						||
| 
								 | 
							
											solvers.spine.useRotationLimits = false;
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											// Aim
							 | 
						||
| 
								 | 
							
											solvers.aim.SetIKPositionWeight(0f);
							 | 
						||
| 
								 | 
							
											solvers.aim.tolerance = 0f;
							 | 
						||
| 
								 | 
							
											solvers.aim.maxIterations = 2;
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											// LookAt
							 | 
						||
| 
								 | 
							
											SetLookAtWeight(0f, 0.5f, 1f, 1f, 0.5f, 0.7f, 0.5f);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										#endregion Main Interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/*
							 | 
						||
| 
								 | 
							
										 * Fixes all the Transforms used by the solver to their default local states.
							 | 
						||
| 
								 | 
							
										 * */
							 | 
						||
| 
								 | 
							
										protected override void FixTransforms() {
							 | 
						||
| 
								 | 
							
								            solvers.pelvis.FixTransforms();
							 | 
						||
| 
								 | 
							
								            solvers.lookAt.FixTransforms();
							 | 
						||
| 
								 | 
							
											for (int i = 0; i < solvers.limbs.Length; i++) solvers.limbs[i].FixTransforms();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/*
							 | 
						||
| 
								 | 
							
										 * Initiates the %IK solver
							 | 
						||
| 
								 | 
							
										 * */
							 | 
						||
| 
								 | 
							
										protected override void InitiateSolver() {
							 | 
						||
| 
								 | 
							
											string message = "";
							 | 
						||
| 
								 | 
							
											if (BipedReferences.SetupError(references, ref message)) {
							 | 
						||
| 
								 | 
							
												Warning.Log(message, references.root, false);
							 | 
						||
| 
								 | 
							
												return;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											solvers.AssignReferences(references);
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											// Initiating solvers
							 | 
						||
| 
								 | 
							
											if (solvers.spine.bones.Length > 1) solvers.spine.Initiate(transform);
							 | 
						||
| 
								 | 
							
											solvers.lookAt.Initiate(transform);
							 | 
						||
| 
								 | 
							
											solvers.aim.Initiate(transform);
							 | 
						||
| 
								 | 
							
											foreach (IKSolverLimb limb in solvers.limbs) limb.Initiate(transform);
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											// Initiating constraints
							 | 
						||
| 
								 | 
							
											solvers.pelvis.Initiate(references.pelvis);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/*
							 | 
						||
| 
								 | 
							
										 * Updates the solvers. If you need full control of the execution order of your IK solvers, disable this script and call UpdateSolver() instead.
							 | 
						||
| 
								 | 
							
										 * */
							 | 
						||
| 
								 | 
							
										protected override void UpdateSolver() {
							 | 
						||
| 
								 | 
							
											// Storing Limb bend and rotation before %IK
							 | 
						||
| 
								 | 
							
											for (int i = 0; i < solvers.limbs.Length; i++) {
							 | 
						||
| 
								 | 
							
												solvers.limbs[i].MaintainBend();
							 | 
						||
| 
								 | 
							
												solvers.limbs[i].MaintainRotation();
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											// Updating constraints
							 | 
						||
| 
								 | 
							
											solvers.pelvis.Update();
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											// Updating %IK solvers
							 | 
						||
| 
								 | 
							
											if (solvers.spine.bones.Length > 1) solvers.spine.Update();
							 | 
						||
| 
								 | 
							
											solvers.aim.Update();
							 | 
						||
| 
								 | 
							
											solvers.lookAt.Update();
							 | 
						||
| 
								 | 
							
											for (int i = 0; i < solvers.limbs.Length; i++) solvers.limbs[i].Update();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/// <summary>
							 | 
						||
| 
								 | 
							
										/// Logs the warning if no other warning has beed logged in this session.
							 | 
						||
| 
								 | 
							
										/// </summary>
							 | 
						||
| 
								 | 
							
										public void LogWarning(string message) {
							 | 
						||
| 
								 | 
							
											Warning.Log(message, transform);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |