BipedIK.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace RootMotion.FinalIK {
  4. /// <summary>
  5. /// %IK system for standard biped characters that is designed to replicate and enhance the behaviour of the Unity's built-in character %IK setup.
  6. /// </summary>
  7. [HelpURL("http://www.root-motion.com/finalikdox/html/page4.html")]
  8. [AddComponentMenu("Scripts/RootMotion.FinalIK/IK/Biped IK")]
  9. public class BipedIK : SolverManager {
  10. // Open the User Manual URL
  11. [ContextMenu("User Manual")]
  12. private void OpenUserManual() {
  13. Application.OpenURL("http://www.root-motion.com/finalikdox/html/page4.html");
  14. }
  15. // Open the Script Reference URL
  16. [ContextMenu("Scrpt Reference")]
  17. private void OpenScriptReference() {
  18. Application.OpenURL("http://www.root-motion.com/finalikdox/html/class_root_motion_1_1_final_i_k_1_1_biped_i_k.html");
  19. }
  20. // Link to the Final IK Google Group
  21. [ContextMenu("Support Group")]
  22. void SupportGroup() {
  23. Application.OpenURL("https://groups.google.com/forum/#!forum/final-ik");
  24. }
  25. // Link to the Final IK Asset Store thread in the Unity Community
  26. [ContextMenu("Asset Store Thread")]
  27. void ASThread() {
  28. Application.OpenURL("http://forum.unity3d.com/threads/final-ik-full-body-ik-aim-look-at-fabrik-ccd-ik-1-0-released.222685/");
  29. }
  30. #region Main Interface
  31. /// <summary>
  32. /// References to character bones.
  33. /// </summary>
  34. public BipedReferences references = new BipedReferences();
  35. /// <summary>
  36. /// The %IK solvers.
  37. /// </summary>
  38. public BipedIKSolvers solvers = new BipedIKSolvers();
  39. /// <summary>
  40. /// Gets the %IK position weight.
  41. /// </summary>
  42. /// <param name='goal'>
  43. /// %IK Goal.
  44. /// </param>
  45. public float GetIKPositionWeight(AvatarIKGoal goal) {
  46. return GetGoalIK(goal).GetIKPositionWeight();
  47. }
  48. /// <summary>
  49. /// Gets the %IK rotation weight.
  50. /// </summary>
  51. /// <param name='goal'>
  52. /// IK Goal.
  53. /// </param>
  54. public float GetIKRotationWeight(AvatarIKGoal goal) {
  55. return GetGoalIK(goal).GetIKRotationWeight();
  56. }
  57. /// <summary>
  58. /// Sets the %IK position weight.
  59. /// </summary>
  60. /// <param name='goal'>
  61. /// %IK Goal.
  62. /// </param>
  63. /// <param name='weight'>
  64. /// Weight.
  65. /// </param>
  66. public void SetIKPositionWeight(AvatarIKGoal goal, float weight) {
  67. GetGoalIK(goal).SetIKPositionWeight(weight);
  68. }
  69. /// <summary>
  70. /// Sets the %IK rotation weight.
  71. /// </summary>
  72. /// <param name='goal'>
  73. /// %IK Goal.
  74. /// </param>
  75. /// <param name='weight'>
  76. /// Weight.
  77. /// </param>
  78. public void SetIKRotationWeight(AvatarIKGoal goal, float weight) {
  79. GetGoalIK(goal).SetIKRotationWeight(weight);
  80. }
  81. /// <summary>
  82. /// Sets the %IK position.
  83. /// </summary>
  84. /// <param name='goal'>
  85. /// %IK Goal.
  86. /// </param>
  87. /// <param name='IKPosition'>
  88. /// Position.
  89. /// </param>
  90. public void SetIKPosition(AvatarIKGoal goal, Vector3 IKPosition) {
  91. GetGoalIK(goal).SetIKPosition(IKPosition);
  92. }
  93. /// <summary>
  94. /// Sets the %IK rotation.
  95. /// </summary>
  96. /// <param name='goal'>
  97. /// %IK Goal.
  98. /// </param>
  99. /// <param name='IKRotation'>
  100. /// Rotation.
  101. /// </param>
  102. public void SetIKRotation(AvatarIKGoal goal, Quaternion IKRotation) {
  103. GetGoalIK(goal).SetIKRotation(IKRotation);
  104. }
  105. /// <summary>
  106. /// Gets the %IK position.
  107. /// </summary>
  108. /// <param name='goal'>
  109. /// %IK Goal.
  110. /// </param>
  111. public Vector3 GetIKPosition(AvatarIKGoal goal) {
  112. return GetGoalIK(goal).GetIKPosition();
  113. }
  114. /// <summary>
  115. /// Gets the %IK rotation.
  116. /// </summary>
  117. /// <param name='goal'>
  118. /// %IK Goal.
  119. /// </param>
  120. public Quaternion GetIKRotation(AvatarIKGoal goal) {
  121. return GetGoalIK(goal).GetIKRotation();
  122. }
  123. /// <summary>
  124. /// Sets the look at weight.
  125. /// </summary>
  126. /// <param name='weight'>
  127. /// Master Weight.
  128. /// </param>
  129. /// <param name='bodyWeight'>
  130. /// Body weight.
  131. /// </param>
  132. /// <param name='headWeight'>
  133. /// Head weight.
  134. /// </param>
  135. /// <param name='eyesWeight'>
  136. /// Eyes weight.
  137. /// </param>
  138. /// <param name='clampWeight'>
  139. /// Clamp weight for body and head.
  140. /// </param>
  141. /// <param name='clampWeightEyes'>
  142. /// Clamp weight for eyes.
  143. /// </param>
  144. public void SetLookAtWeight(float weight, float bodyWeight , float headWeight, float eyesWeight, float clampWeight, float clampWeightHead, float clampWeightEyes) {
  145. solvers.lookAt.SetLookAtWeight(weight, bodyWeight, headWeight, eyesWeight, clampWeight, clampWeightHead, clampWeightEyes);
  146. }
  147. /// <summary>
  148. /// Sets the look at target.
  149. /// </summary>
  150. /// <param name='lookAtPosition'>
  151. /// Look at position.
  152. /// </param>
  153. public void SetLookAtPosition(Vector3 lookAtPosition) {
  154. solvers.lookAt.SetIKPosition(lookAtPosition);
  155. }
  156. /// <summary>
  157. /// Sets the spine %IK position.
  158. /// </summary>
  159. /// <param name='spinePosition'>
  160. /// Spine %IK position.
  161. /// </param>
  162. public void SetSpinePosition(Vector3 spinePosition) {
  163. solvers.spine.SetIKPosition(spinePosition);
  164. }
  165. /// <summary>
  166. /// Sets the spine weight.
  167. /// </summary>
  168. /// <param name='weight'>
  169. /// Weight.
  170. /// </param>
  171. public void SetSpineWeight(float weight) {
  172. solvers.spine.SetIKPositionWeight(weight);
  173. }
  174. /// <summary>
  175. /// Gets the limb solver for the %IK Goal.
  176. /// </summary>
  177. /// <returns>
  178. /// The solver.
  179. /// </returns>
  180. /// <param name='goal'>
  181. /// %IK Goal.
  182. /// </param>
  183. public IKSolverLimb GetGoalIK(AvatarIKGoal goal) {
  184. switch(goal) {
  185. case AvatarIKGoal.LeftFoot: return solvers.leftFoot;
  186. case AvatarIKGoal.RightFoot: return solvers.rightFoot;
  187. case AvatarIKGoal.LeftHand: return solvers.leftHand;
  188. case AvatarIKGoal.RightHand: return solvers.rightHand;
  189. }
  190. return null;
  191. }
  192. /// <summary>
  193. /// (Re)Initiates the biped IK solvers.
  194. /// </summary>
  195. public void InitiateBipedIK() {
  196. InitiateSolver();
  197. }
  198. /// <summary>
  199. /// Updating BipedIK
  200. /// </summary>
  201. public void UpdateBipedIK() {
  202. UpdateSolver();
  203. }
  204. /*
  205. * Set default solver values.
  206. * */
  207. public void SetToDefaults() {
  208. // Limbs
  209. foreach (IKSolverLimb limb in solvers.limbs) {
  210. limb.SetIKPositionWeight(0f);
  211. limb.SetIKRotationWeight(0f);
  212. limb.bendModifier = IKSolverLimb.BendModifier.Animation;
  213. limb.bendModifierWeight = 1f;
  214. }
  215. solvers.leftHand.maintainRotationWeight = 0f;
  216. solvers.rightHand.maintainRotationWeight = 0f;
  217. // Spine
  218. solvers.spine.SetIKPositionWeight(0f);
  219. solvers.spine.tolerance = 0f;
  220. solvers.spine.maxIterations = 2;
  221. solvers.spine.useRotationLimits = false;
  222. // Aim
  223. solvers.aim.SetIKPositionWeight(0f);
  224. solvers.aim.tolerance = 0f;
  225. solvers.aim.maxIterations = 2;
  226. // LookAt
  227. SetLookAtWeight(0f, 0.5f, 1f, 1f, 0.5f, 0.7f, 0.5f);
  228. }
  229. #endregion Main Interface
  230. /*
  231. * Fixes all the Transforms used by the solver to their default local states.
  232. * */
  233. protected override void FixTransforms() {
  234. solvers.lookAt.FixTransforms();
  235. for (int i = 0; i < solvers.limbs.Length; i++) solvers.limbs[i].FixTransforms();
  236. }
  237. /*
  238. * Initiates the %IK solver
  239. * */
  240. protected override void InitiateSolver() {
  241. string message = "";
  242. if (BipedReferences.SetupError(references, ref message)) {
  243. Warning.Log(message, references.root, false);
  244. return;
  245. }
  246. solvers.AssignReferences(references);
  247. // Initiating solvers
  248. if (solvers.spine.bones.Length > 1) solvers.spine.Initiate(transform);
  249. solvers.lookAt.Initiate(transform);
  250. solvers.aim.Initiate(transform);
  251. foreach (IKSolverLimb limb in solvers.limbs) limb.Initiate(transform);
  252. // Initiating constraints
  253. solvers.pelvis.Initiate(references.pelvis);
  254. }
  255. /*
  256. * Updates the solvers. If you need full control of the execution order of your IK solvers, disable this script and call UpdateSolver() instead.
  257. * */
  258. protected override void UpdateSolver() {
  259. // Storing Limb bend and rotation before %IK
  260. for (int i = 0; i < solvers.limbs.Length; i++) {
  261. solvers.limbs[i].MaintainBend();
  262. solvers.limbs[i].MaintainRotation();
  263. }
  264. // Updating constraints
  265. solvers.pelvis.Update();
  266. // Updating %IK solvers
  267. if (solvers.spine.bones.Length > 1) solvers.spine.Update();
  268. solvers.aim.Update();
  269. solvers.lookAt.Update();
  270. for (int i = 0; i < solvers.limbs.Length; i++) solvers.limbs[i].Update();
  271. }
  272. /// <summary>
  273. /// Logs the warning if no other warning has beed logged in this session.
  274. /// </summary>
  275. public void LogWarning(string message) {
  276. Warning.Log(message, transform);
  277. }
  278. }
  279. }