VRIKRootController.cs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace RootMotion.FinalIK
  4. {
  5. public class VRIKRootController : MonoBehaviour
  6. {
  7. public Vector3 pelvisTargetRight { get; private set; }
  8. private Transform pelvisTarget;
  9. private Transform leftFootTarget;
  10. private Transform rightFootTarget;
  11. private VRIK ik;
  12. void Awake()
  13. {
  14. ik = GetComponent<VRIK>();
  15. ik.solver.OnPreUpdate += OnPreUpdate;
  16. Calibrate();
  17. }
  18. public void Calibrate()
  19. {
  20. if (ik == null)
  21. {
  22. Debug.LogError("No VRIK found on VRIKRootController's GameObject.", transform);
  23. return;
  24. }
  25. pelvisTarget = ik.solver.spine.pelvisTarget;
  26. leftFootTarget = ik.solver.leftLeg.target;
  27. rightFootTarget = ik.solver.rightLeg.target;
  28. if (pelvisTarget != null) pelvisTargetRight = Quaternion.Inverse(pelvisTarget.rotation) * ik.references.root.right;
  29. }
  30. public void Calibrate(VRIKCalibrator.CalibrationData data)
  31. {
  32. if (ik == null)
  33. {
  34. Debug.LogError("No VRIK found on VRIKRootController's GameObject.", transform);
  35. return;
  36. }
  37. pelvisTarget = ik.solver.spine.pelvisTarget;
  38. leftFootTarget = ik.solver.leftLeg.target;
  39. rightFootTarget = ik.solver.rightLeg.target;
  40. if (pelvisTarget != null)
  41. {
  42. pelvisTargetRight = data.pelvisTargetRight;
  43. }
  44. }
  45. void OnPreUpdate()
  46. {
  47. if (!enabled) return;
  48. if (pelvisTarget != null)
  49. {
  50. ik.references.root.position = new Vector3(pelvisTarget.position.x, ik.references.root.position.y, pelvisTarget.position.z);
  51. Vector3 f = Vector3.Cross(pelvisTarget.rotation * pelvisTargetRight, ik.references.root.up);
  52. f.y = 0f;
  53. ik.references.root.rotation = Quaternion.LookRotation(f);
  54. ik.references.pelvis.position = Vector3.Lerp(ik.references.pelvis.position, pelvisTarget.position, ik.solver.spine.pelvisPositionWeight);
  55. ik.references.pelvis.rotation = Quaternion.Slerp(ik.references.pelvis.rotation, pelvisTarget.rotation, ik.solver.spine.pelvisRotationWeight);
  56. }
  57. else if (leftFootTarget != null && rightFootTarget != null)
  58. {
  59. ik.references.root.position = Vector3.Lerp(leftFootTarget.position, rightFootTarget.position, 0.5f);
  60. }
  61. }
  62. void OnDestroy()
  63. {
  64. if (ik != null) ik.solver.OnPreUpdate -= OnPreUpdate;
  65. }
  66. }
  67. }