Inertia.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace RootMotion.FinalIK {
  4. /// <summary>
  5. /// Demo script that adds the illusion of mass to your character using FullBodyBipedIK.
  6. /// </summary>
  7. public class Inertia : OffsetModifier {
  8. /// <summary>
  9. /// Body is just following it's transform in a lazy and bouncy way.
  10. /// </summary>
  11. [System.Serializable]
  12. public class Body {
  13. /// <summary>
  14. /// Linking this to an effector
  15. /// </summary>
  16. [System.Serializable]
  17. public class EffectorLink {
  18. [Tooltip("Type of the FBBIK effector to use")]
  19. public FullBodyBipedEffector effector;
  20. [Tooltip("Weight of using this effector")]
  21. public float weight;
  22. }
  23. [Tooltip("The Transform to follow, can be any bone of the character")]
  24. public Transform transform;
  25. [Tooltip("Linking the body to effectors. One Body can be used to offset more than one effector")]
  26. public EffectorLink[] effectorLinks;
  27. [Tooltip("The speed to follow the Transform")]
  28. public float speed = 10f;
  29. [Tooltip("The acceleration, smaller values means lazyer following")]
  30. public float acceleration = 3f;
  31. [Tooltip("Matching target velocity")]
  32. [Range(0f, 1f)] public float matchVelocity;
  33. [Tooltip("gravity applied to the Body")]
  34. public float gravity;
  35. private Vector3 delta;
  36. private Vector3 lazyPoint;
  37. private Vector3 direction;
  38. private Vector3 lastPosition;
  39. private bool firstUpdate = true;
  40. // Reset to Transform
  41. public void Reset() {
  42. if (transform == null) return;
  43. lazyPoint = transform.position;
  44. lastPosition = transform.position;
  45. direction = Vector3.zero;
  46. }
  47. // Update this body, apply the offset to the effector
  48. public void Update(IKSolverFullBodyBiped solver, float weight, float deltaTime) {
  49. if (transform == null) return;
  50. // If first update, set this body to Transform
  51. if (firstUpdate) {
  52. Reset();
  53. firstUpdate = false;
  54. }
  55. // Acceleration
  56. direction = Vector3.Lerp(direction, ((transform.position - lazyPoint) / deltaTime) * 0.01f, deltaTime * acceleration);
  57. // Lazy follow
  58. lazyPoint += direction * deltaTime * speed;
  59. // Match velocity
  60. delta = transform.position - lastPosition;
  61. lazyPoint += delta * matchVelocity;
  62. // Gravity
  63. lazyPoint.y += gravity * deltaTime;
  64. // Apply position offset to the effector
  65. foreach (EffectorLink effectorLink in effectorLinks) {
  66. solver.GetEffector(effectorLink.effector).positionOffset += (lazyPoint - transform.position) * effectorLink.weight * weight;
  67. }
  68. lastPosition = transform.position;
  69. }
  70. }
  71. [Tooltip("The array of Bodies")]
  72. public Body[] bodies;
  73. [Tooltip("The array of OffsetLimits")]
  74. public OffsetLimits[] limits;
  75. // Reset all Bodies
  76. public void ResetBodies() {
  77. lastTime = Time.time;
  78. foreach (Body body in bodies) body.Reset();
  79. }
  80. // Called by IKSolverFullBody before updating
  81. protected override void OnModifyOffset() {
  82. // Update the Bodies
  83. foreach (Body body in bodies) body.Update(ik.solver, weight, deltaTime);
  84. // Apply the offset limits
  85. ApplyLimits(limits);
  86. }
  87. }
  88. }