IKSolverVRFootstep.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.Events;
  4. namespace RootMotion.FinalIK {
  5. public partial class IKSolverVR: IKSolver {
  6. [System.Serializable]
  7. public class Footstep {
  8. public float stepSpeed = 3f;
  9. public Vector3 characterSpaceOffset;
  10. public Vector3 position;
  11. public Quaternion rotation = Quaternion.identity;
  12. public Quaternion stepToRootRot = Quaternion.identity;
  13. public bool isStepping { get { return stepProgress < 1f; }}
  14. public bool isSupportLeg;
  15. public bool relaxFlag;
  16. public float stepProgress { get; private set; }
  17. public Vector3 stepFrom;
  18. public Vector3 stepTo;
  19. public Quaternion stepFromRot = Quaternion.identity;
  20. public Quaternion stepToRot = Quaternion.identity;
  21. private Quaternion footRelativeToRoot = Quaternion.identity;
  22. private float supportLegW;
  23. private float supportLegWV;
  24. public Footstep (Quaternion rootRotation, Vector3 footPosition, Quaternion footRotation, Vector3 characterSpaceOffset) {
  25. this.characterSpaceOffset = characterSpaceOffset;
  26. Reset(rootRotation, footPosition, footRotation);
  27. footRelativeToRoot = Quaternion.Inverse(rootRotation) * rotation;
  28. }
  29. public void Reset(Quaternion rootRotation, Vector3 footPosition, Quaternion footRotation) {
  30. position = footPosition;
  31. rotation = footRotation;
  32. stepFrom = position;
  33. stepTo = position;
  34. stepFromRot = rotation;
  35. stepToRot = rotation;
  36. stepToRootRot = rootRotation;
  37. stepProgress = 1f;
  38. }
  39. public void StepTo(Vector3 p, Quaternion rootRotation, float stepThreshold) {
  40. if (relaxFlag)
  41. {
  42. stepThreshold = 0f;
  43. relaxFlag = false;
  44. }
  45. if (Vector3.Magnitude(p - stepTo) < stepThreshold && Quaternion.Angle(rootRotation, stepToRootRot) < 25f) return;
  46. stepFrom = position;
  47. stepTo = p;
  48. stepFromRot = rotation;
  49. stepToRootRot = rootRotation;
  50. stepToRot = rootRotation * footRelativeToRoot;
  51. stepProgress = 0f;
  52. }
  53. public void UpdateStepping(Vector3 p, Quaternion rootRotation, float speed) {
  54. stepTo = Vector3.Lerp (stepTo, p, Time.deltaTime * speed);
  55. stepToRot = Quaternion.Lerp (stepToRot, rootRotation * footRelativeToRoot, Time.deltaTime * speed);
  56. stepToRootRot = stepToRot * Quaternion.Inverse(footRelativeToRoot);
  57. }
  58. public void UpdateStanding(Quaternion rootRotation, float minAngle, float speed) {
  59. if (speed <= 0f || minAngle >= 180f) return;
  60. Quaternion r = rootRotation * footRelativeToRoot;
  61. float angle = Quaternion.Angle (rotation, r);
  62. if (angle > minAngle) rotation = Quaternion.RotateTowards (rotation, r, Mathf.Min (Time.deltaTime * speed * (1f - supportLegW), angle -minAngle));
  63. }
  64. public void Update(InterpolationMode interpolation, UnityEvent onStep) {
  65. float supportLegWTarget = isSupportLeg ? 1f : 0f;
  66. supportLegW = Mathf.SmoothDamp (supportLegW, supportLegWTarget, ref supportLegWV, 0.2f);
  67. if (!isStepping) return;
  68. stepProgress = Mathf.MoveTowards(stepProgress, 1f, Time.deltaTime * stepSpeed);
  69. if (stepProgress >= 1f) onStep.Invoke ();
  70. float stepProgressSmooth = RootMotion.Interp.Float(stepProgress, interpolation);
  71. position = Vector3.Lerp(stepFrom, stepTo, stepProgressSmooth);
  72. rotation = Quaternion.Lerp(stepFromRot, stepToRot, stepProgressSmooth);
  73. }
  74. }
  75. }
  76. }