IKSolverArm.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace RootMotion.FinalIK {
  4. /// <summary>
  5. /// A wrapper for making IKSolverVRArm work with other IK components.
  6. /// </summary>
  7. [System.Serializable]
  8. public class IKSolverArm : 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 chest = new IKSolver.Point();
  16. public IKSolver.Point shoulder = new IKSolver.Point();
  17. public IKSolver.Point upperArm = new IKSolver.Point();
  18. public IKSolver.Point forearm = new IKSolver.Point();
  19. public IKSolver.Point hand = new IKSolver.Point();
  20. public bool isLeft;
  21. public IKSolverVR.Arm arm = new IKSolverVR.Arm();
  22. private Vector3[] positions = new Vector3[6];
  23. private Quaternion[] rotations = new Quaternion[6];
  24. public override bool IsValid(ref string message) {
  25. if (chest.transform == null || shoulder.transform == null || upperArm.transform == null || forearm.transform == null || hand.transform == null) {
  26. message = "Please assign all bone slots of the Arm IK solver.";
  27. return false;
  28. }
  29. Transform duplicate = (Transform)Hierarchy.ContainsDuplicate(new Transform[5] { chest.transform, shoulder.transform, upperArm.transform, forearm.transform, hand.transform });
  30. if (duplicate != null) {
  31. message = duplicate.name + " is represented multiple times in the ArmIK.";
  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 chest, Transform shoulder, Transform upperArm, Transform forearm, Transform hand, Transform root) {
  43. this.chest.transform = chest;
  44. this.shoulder.transform = shoulder;
  45. this.upperArm.transform = upperArm;
  46. this.forearm.transform = forearm;
  47. this.hand.transform = hand;
  48. Initiate(root);
  49. return initiated;
  50. }
  51. public override IKSolver.Point[] GetPoints() {
  52. return new IKSolver.Point[5] { (IKSolver.Point)chest, (IKSolver.Point)shoulder, (IKSolver.Point)upperArm, (IKSolver.Point)forearm, (IKSolver.Point)hand };
  53. }
  54. public override IKSolver.Point GetPoint(Transform transform) {
  55. if (chest.transform == transform) return (IKSolver.Point)chest;
  56. if (shoulder.transform == transform) return (IKSolver.Point)shoulder;
  57. if (upperArm.transform == transform) return (IKSolver.Point)upperArm;
  58. if (forearm.transform == transform) return (IKSolver.Point)forearm;
  59. if (hand.transform == transform) return (IKSolver.Point)hand;
  60. return null;
  61. }
  62. public override void StoreDefaultLocalState() {
  63. shoulder.StoreDefaultLocalState();
  64. upperArm.StoreDefaultLocalState();
  65. forearm.StoreDefaultLocalState();
  66. hand.StoreDefaultLocalState();
  67. }
  68. public override void FixTransforms() {
  69. if (!initiated) return;
  70. shoulder.FixTransform();
  71. upperArm.FixTransform();
  72. forearm.FixTransform();
  73. hand.FixTransform();
  74. }
  75. protected override void OnInitiate() {
  76. IKPosition = hand.transform.position;
  77. IKRotation = hand.transform.rotation;
  78. Read ();
  79. }
  80. protected override void OnUpdate() {
  81. Read ();
  82. Solve ();
  83. Write ();
  84. }
  85. private void Solve() {
  86. arm.PreSolve ();
  87. arm.ApplyOffsets(1f);
  88. arm.Solve (isLeft);
  89. arm.ResetOffsets ();
  90. }
  91. private void Read() {
  92. arm.IKPosition = IKPosition;
  93. arm.positionWeight = IKPositionWeight;
  94. arm.IKRotation = IKRotation;
  95. arm.rotationWeight = IKRotationWeight;
  96. positions [0] = root.position;
  97. positions [1] = chest.transform.position;
  98. positions [2] = shoulder.transform.position;
  99. positions [3] = upperArm.transform.position;
  100. positions [4] = forearm.transform.position;
  101. positions [5] = hand.transform.position;
  102. rotations [0] = root.rotation;
  103. rotations [1] = chest.transform.rotation;
  104. rotations [2] = shoulder.transform.rotation;
  105. rotations [3] = upperArm.transform.rotation;
  106. rotations [4] = forearm.transform.rotation;
  107. rotations [5] = hand.transform.rotation;
  108. arm.Read(positions, rotations, false, false, true, false, false, 1, 2);
  109. }
  110. private void Write() {
  111. arm.Write (ref positions, ref rotations);
  112. shoulder.transform.rotation = rotations [2];
  113. upperArm.transform.rotation = rotations [3];
  114. forearm.transform.rotation = rotations [4];
  115. hand.transform.rotation = rotations [5];
  116. forearm.transform.position = positions[4];
  117. hand.transform.position = positions[5];
  118. }
  119. }
  120. }