IKSolverLeg.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace RootMotion.FinalIK {
  4. /// <summary>
  5. /// A wrapper for making IKSolverVRLeg work with other IK components and the Grounder.
  6. /// </summary>
  7. [System.Serializable]
  8. public class IKSolverLeg : IKSolver {
  9. [Range(0f, 1f)]
  10. public float IKRotationWeight = 1f;
  11. /// <summary>
  12. /// The %IK rotation target.
  13. /// </summary>
  14. public Quaternion IKRotation = Quaternion.identity;
  15. public IKSolver.Point pelvis = new IKSolver.Point();
  16. public IKSolver.Point thigh = new IKSolver.Point();
  17. public IKSolver.Point calf = new IKSolver.Point();
  18. public IKSolver.Point foot = new IKSolver.Point();
  19. public IKSolver.Point toe = new IKSolver.Point();
  20. public IKSolverVR.Leg leg = new IKSolverVR.Leg();
  21. public Vector3 heelOffset;
  22. private Vector3[] positions = new Vector3[6];
  23. private Quaternion[] rotations = new Quaternion[6];
  24. public override bool IsValid(ref string message) {
  25. if (pelvis.transform == null || thigh.transform == null || calf.transform == null || foot.transform == null || toe.transform == null) {
  26. message = "Please assign all bone slots of the Leg IK solver.";
  27. return false;
  28. }
  29. Transform duplicate = (Transform)Hierarchy.ContainsDuplicate(new Transform[5] { pelvis.transform, thigh.transform, calf.transform, foot.transform, toe.transform });
  30. if (duplicate != null) {
  31. message = duplicate.name + " is represented multiple times in the LegIK.";
  32. return false;
  33. }
  34. return true;
  35. }
  36. /// <summary>
  37. /// Reinitiate the solver with new bone Transforms.
  38. /// </summary>
  39. /// <returns>
  40. /// Returns true if the new chain is valid.
  41. /// </returns>
  42. public bool SetChain(Transform pelvis, Transform thigh, Transform calf, Transform foot, Transform toe, Transform root) {
  43. this.pelvis.transform = pelvis;
  44. this.thigh.transform = thigh;
  45. this.calf.transform = calf;
  46. this.foot.transform = foot;
  47. this.toe.transform = toe;
  48. Initiate(root);
  49. return initiated;
  50. }
  51. public override IKSolver.Point[] GetPoints() {
  52. return new IKSolver.Point[5] { (IKSolver.Point)pelvis, (IKSolver.Point)thigh, (IKSolver.Point)calf, (IKSolver.Point)foot, (IKSolver.Point)toe };
  53. }
  54. public override IKSolver.Point GetPoint(Transform transform) {
  55. if (pelvis.transform == transform) return (IKSolver.Point)pelvis;
  56. if (thigh.transform == transform) return (IKSolver.Point)thigh;
  57. if (calf.transform == transform) return (IKSolver.Point)calf;
  58. if (foot.transform == transform) return (IKSolver.Point)foot;
  59. if (toe.transform == transform) return (IKSolver.Point)toe;
  60. return null;
  61. }
  62. public override void StoreDefaultLocalState() {
  63. thigh.StoreDefaultLocalState();
  64. calf.StoreDefaultLocalState();
  65. foot.StoreDefaultLocalState();
  66. toe.StoreDefaultLocalState();
  67. }
  68. public override void FixTransforms() {
  69. if (!initiated) return;
  70. thigh.FixTransform();
  71. calf.FixTransform();
  72. foot.FixTransform();
  73. toe.FixTransform();
  74. }
  75. protected override void OnInitiate() {
  76. IKPosition = toe.transform.position;
  77. IKRotation = toe.transform.rotation;
  78. Read ();
  79. }
  80. protected override void OnUpdate() {
  81. Read ();
  82. Solve ();
  83. Write ();
  84. }
  85. private void Solve() {
  86. leg.heelPositionOffset += heelOffset;
  87. leg.PreSolve ();
  88. leg.ApplyOffsets(1f);
  89. leg.Solve (true);
  90. leg.ResetOffsets ();
  91. }
  92. private void Read() {
  93. leg.IKPosition = IKPosition;
  94. leg.positionWeight = IKPositionWeight;
  95. leg.IKRotation = IKRotation;
  96. leg.rotationWeight = IKRotationWeight;
  97. positions [0] = root.position;
  98. positions [1] = pelvis.transform.position;
  99. positions [2] = thigh.transform.position;
  100. positions [3] = calf.transform.position;
  101. positions [4] = foot.transform.position;
  102. positions [5] = toe.transform.position;
  103. rotations [0] = root.rotation;
  104. rotations [1] = pelvis.transform.rotation;
  105. rotations [2] = thigh.transform.rotation;
  106. rotations [3] = calf.transform.rotation;
  107. rotations [4] = foot.transform.rotation;
  108. rotations [5] = toe.transform.rotation;
  109. leg.Read(positions, rotations, false, false, false, true, true, 1, 2);
  110. }
  111. private void Write() {
  112. leg.Write (ref positions, ref rotations);
  113. thigh.transform.rotation = rotations [2];
  114. calf.transform.rotation = rotations [3];
  115. foot.transform.rotation = rotations [4];
  116. toe.transform.rotation = rotations [5];
  117. calf.transform.position = positions[3];
  118. foot.transform.position = positions[4];
  119. }
  120. }
  121. }