GrounderVRIK.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace RootMotion.FinalIK {
  4. /// <summary>
  5. /// Grounding for FBBIK characters.
  6. /// </summary>
  7. [HelpURL("https://www.youtube.com/watch?v=9MiZiaJorws&index=6&list=PLVxSIA1OaTOu8Nos3CalXbJ2DrKnntMv6")]
  8. [AddComponentMenu("Scripts/RootMotion.FinalIK/Grounder/Grounder VRIK")]
  9. public class GrounderVRIK: Grounder {
  10. // Open a video tutorial video
  11. [ContextMenu("TUTORIAL VIDEO")]
  12. void OpenTutorial() {
  13. Application.OpenURL("https://www.youtube.com/watch?v=9MiZiaJorws&index=6&list=PLVxSIA1OaTOu8Nos3CalXbJ2DrKnntMv6");
  14. }
  15. // Open the User Manual URL
  16. [ContextMenu("User Manual")]
  17. protected override void OpenUserManual() {
  18. Application.OpenURL("http://www.root-motion.com/finalikdox/html/page9.html");
  19. }
  20. // Open the Script Reference URL
  21. [ContextMenu("Scrpt Reference")]
  22. protected override void OpenScriptReference() {
  23. Application.OpenURL("http://www.root-motion.com/finalikdox/html/class_root_motion_1_1_final_i_k_1_1_grounder_v_r_i_k.html");
  24. }
  25. #region Main Interface
  26. /// <summary>
  27. /// Reference to the VRIK componet.
  28. /// </summary>
  29. [Tooltip("Reference to the VRIK componet.")]
  30. public VRIK ik;
  31. #endregion Main Interface
  32. public override void ResetPosition() {
  33. solver.Reset();
  34. }
  35. private Transform[] feet = new Transform[2];
  36. // Can we initiate the Grounding?
  37. private bool IsReadyToInitiate() {
  38. if (ik == null) return false;
  39. if (!ik.solver.initiated) return false;
  40. return true;
  41. }
  42. // Initiate once we have a FBBIK component
  43. void Update() {
  44. weight = Mathf.Clamp(weight, 0f, 1f);
  45. if (weight <= 0f) return;
  46. if (initiated) return;
  47. if (!IsReadyToInitiate()) return;
  48. Initiate();
  49. }
  50. private void Initiate () {
  51. // Gathering both foot bones from the FBBIK
  52. feet = new Transform[2];
  53. feet[0] = ik.references.leftFoot;
  54. feet[1] = ik.references.rightFoot;
  55. // Add to the FBBIK OnPreUpdate delegate to know when it solves
  56. ik.solver.OnPreUpdate += OnSolverUpdate;
  57. ik.solver.OnPostUpdate += OnPostSolverUpdate;
  58. // Initiate Grounding
  59. solver.Initiate(ik.references.root, feet);
  60. initiated = true;
  61. }
  62. // Called before updating the main IK solver
  63. private void OnSolverUpdate() {
  64. if (!enabled) return;
  65. if (weight <= 0f) return;
  66. if (OnPreGrounder != null) OnPreGrounder();
  67. /*
  68. Vector3 leftFootPos = ik.references.leftFoot.position;
  69. Vector3 rightFootPos = ik.references.rightFoot.position;
  70. ik.references.leftFoot.position = ik.solver.locomotion.leftFootstepPosition;
  71. ik.references.rightFoot.position = ik.solver.locomotion.rightFootstepPosition;
  72. */
  73. solver.Update();
  74. //ik.references.leftFoot.position = leftFootPos;
  75. //ik.references.rightFoot.position = rightFootPos;
  76. // Move the pelvis
  77. ik.references.pelvis.position += solver.pelvis.IKOffset * weight;
  78. // Set effector positionOffsets for the feet
  79. ik.solver.AddPositionOffset (IKSolverVR.PositionOffset.LeftFoot, (solver.legs[0].IKPosition - ik.references.leftFoot.position) * weight);
  80. ik.solver.AddPositionOffset (IKSolverVR.PositionOffset.RightFoot, (solver.legs[1].IKPosition - ik.references.rightFoot.position) * weight);
  81. if (OnPostGrounder != null) OnPostGrounder();
  82. }
  83. // Set the effector positionOffset for the foot
  84. private void SetLegIK(IKSolverVR.PositionOffset positionOffset, Transform bone, Grounding.Leg leg) {
  85. ik.solver.AddPositionOffset (positionOffset, (leg.IKPosition - bone.position) * weight);
  86. }
  87. void OnPostSolverUpdate() {
  88. ik.references.leftFoot.rotation = Quaternion.Slerp(Quaternion.identity, solver.legs[0].rotationOffset, weight) * ik.references.leftFoot.rotation;
  89. ik.references.rightFoot.rotation = Quaternion.Slerp(Quaternion.identity, solver.legs[1].rotationOffset, weight) * ik.references.rightFoot.rotation;
  90. }
  91. // Auto-assign ik
  92. void OnDrawGizmosSelected() {
  93. if (ik == null) ik = GetComponent<VRIK>();
  94. if (ik == null) ik = GetComponentInParent<VRIK>();
  95. if (ik == null) ik = GetComponentInChildren<VRIK>();
  96. }
  97. // Cleaning up the delegate
  98. void OnDestroy() {
  99. if (initiated && ik != null) {
  100. ik.solver.OnPreUpdate -= OnSolverUpdate;
  101. ik.solver.OnPostUpdate -= OnPostSolverUpdate;
  102. }
  103. }
  104. }
  105. }