InteractionTarget.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. using UnityEngine;
  2. using System.Collections;
  3. using RootMotion;
  4. namespace RootMotion.FinalIK {
  5. /// <summary>
  6. /// The target of an effector in the InteractionSystem.
  7. /// </summary>
  8. [HelpURL("https://www.youtube.com/watch?v=r5jiZnsDH3M")]
  9. [AddComponentMenu("Scripts/RootMotion.FinalIK/Interaction System/Interaction Target")]
  10. public class InteractionTarget : MonoBehaviour {
  11. [System.Serializable]
  12. public enum RotationMode
  13. {
  14. TwoDOF = 0,
  15. ThreeDOF = 1
  16. }
  17. // Open the User Manual URL
  18. [ContextMenu("User Manual")]
  19. void OpenUserManual()
  20. {
  21. Application.OpenURL("http://www.root-motion.com/finalikdox/html/page10.html");
  22. }
  23. // Open the Script Reference URL
  24. [ContextMenu("Scrpt Reference")]
  25. void OpenScriptReference()
  26. {
  27. Application.OpenURL("http://www.root-motion.com/finalikdox/html/class_root_motion_1_1_final_i_k_1_1_interaction_target.html");
  28. }
  29. // Open a video tutorial video
  30. [ContextMenu("TUTORIAL VIDEO (PART 1: BASICS)")]
  31. void OpenTutorial1() {
  32. Application.OpenURL("https://www.youtube.com/watch?v=r5jiZnsDH3M");
  33. }
  34. // Open a video tutorial video
  35. [ContextMenu("TUTORIAL VIDEO (PART 2: PICKING UP...)")]
  36. void OpenTutorial2() {
  37. Application.OpenURL("https://www.youtube.com/watch?v=eP9-zycoHLk");
  38. }
  39. // Open a video tutorial video
  40. [ContextMenu("TUTORIAL VIDEO (PART 3: ANIMATION)")]
  41. void OpenTutorial3() {
  42. Application.OpenURL("https://www.youtube.com/watch?v=sQfB2RcT1T4&index=14&list=PLVxSIA1OaTOu8Nos3CalXbJ2DrKnntMv6");
  43. }
  44. // Open a video tutorial video
  45. [ContextMenu("TUTORIAL VIDEO (PART 4: TRIGGERS)")]
  46. void OpenTutorial4() {
  47. Application.OpenURL("https://www.youtube.com/watch?v=-TDZpNjt2mk&index=15&list=PLVxSIA1OaTOu8Nos3CalXbJ2DrKnntMv6");
  48. }
  49. // Link to the Final IK Google Group
  50. [ContextMenu("Support Group")]
  51. void SupportGroup() {
  52. Application.OpenURL("https://groups.google.com/forum/#!forum/final-ik");
  53. }
  54. // Link to the Final IK Asset Store thread in the Unity Community
  55. [ContextMenu("Asset Store Thread")]
  56. void ASThread() {
  57. Application.OpenURL("http://forum.unity3d.com/threads/final-ik-full-body-ik-aim-look-at-fabrik-ccd-ik-1-0-released.222685/");
  58. }
  59. /// <summary>
  60. /// Multiplies the value of a weight curve for this effector target.
  61. /// </summary>
  62. [System.Serializable]
  63. public class Multiplier {
  64. /// <summary>
  65. /// The curve type (InteractionObject.WeightCurve.Type).
  66. /// </summary>
  67. [Tooltip("The curve type (InteractionObject.WeightCurve.Type).")]
  68. public InteractionObject.WeightCurve.Type curve;
  69. /// <summary>
  70. /// Multiplier of the curve's value.
  71. /// </summary>
  72. [Tooltip("Multiplier of the curve's value.")]
  73. public float multiplier;
  74. }
  75. /// <summary>
  76. /// The type of the FBBIK effector.
  77. /// </summary>
  78. [Tooltip("The type of the FBBIK effector.")]
  79. public FullBodyBipedEffector effectorType;
  80. /// <summary>
  81. /// InteractionObject weight curve multipliers for this effector target.
  82. /// </summary>
  83. [Tooltip("InteractionObject weight curve multipliers for this effector target.")]
  84. public Multiplier[] multipliers;
  85. /// <summary>
  86. /// The interaction speed multiplier for this effector. This can be used to make interactions faster/slower for specific effectors.
  87. /// </summary>
  88. [Tooltip("The interaction speed multiplier for this effector. This can be used to make interactions faster/slower for specific effectors.")]
  89. public float interactionSpeedMlp = 1f;
  90. /// <summary>
  91. /// The pivot to twist/swing this interaction target about. For symmetric objects that can be interacted with from a certain angular range.
  92. /// </summary>
  93. [Tooltip("The pivot to twist/swing this interaction target about. For symmetric objects that can be interacted with from a certain angular range.")]
  94. public Transform pivot;
  95. /// <summary>
  96. /// 2 or 3 degrees of freedom to match this InteractionTarget's rotation to the effector bone rotation.
  97. /// </summary>
  98. [Tooltip("2 or 3 degrees of freedom to match this InteractionTarget's rotation to the effector bone rotation.")]
  99. public RotationMode rotationMode;
  100. /// <summary>
  101. /// The axis of twisting the interaction target.
  102. /// </summary>
  103. [Tooltip("The axis of twisting the interaction target (blue line).")]
  104. public Vector3 twistAxis = Vector3.up;
  105. /// <summary>
  106. /// The weight of twisting the interaction target towards the effector bone in the start of the interaction.
  107. /// </summary>
  108. [Tooltip("The weight of twisting the interaction target towards the effector bone in the start of the interaction.")]
  109. public float twistWeight = 1f;
  110. /// <summary>
  111. /// The weight of swinging the interaction target towards the effector bone in the start of the interaction. Swing is defined as a 3-DOF rotation around any axis, while twist is only around the twist axis.
  112. /// </summary>
  113. [Tooltip("The weight of swinging the interaction target towards the effector bone in the start of the interaction. Swing is defined as a 3-DOF rotation around any axis, while twist is only around the twist axis.")]
  114. public float swingWeight;
  115. /// <summary>
  116. /// The weight of rotating this InteractionTarget to the effector bone in the start of the interaction (and during if 'Rotate Once' is disabled
  117. /// </summary>
  118. [Tooltip("The weight of rotating this InteractionTarget to the effector bone in the start of the interaction (and during if 'Rotate Once' is disabled")]
  119. [Range(0f, 1f)] public float threeDOFWeight = 1f;
  120. /// <summary>
  121. /// If true, will twist/swing around the pivot only once at the start of the interaction. If false, will continue rotating throuout the whole interaction.
  122. /// </summary>
  123. [Tooltip("If true, will twist/swing around the pivot only once at the start of the interaction. If false, will continue rotating throuout the whole interaction.")]
  124. public bool rotateOnce = true;
  125. private Quaternion defaultLocalRotation;
  126. private Transform lastPivot;
  127. // Should a curve of the Type be ignored for this effector?
  128. public float GetValue(InteractionObject.WeightCurve.Type curveType) {
  129. for (int i = 0; i < multipliers.Length; i++) if (multipliers[i].curve == curveType) return multipliers[i].multiplier;
  130. return 1f;
  131. }
  132. // Reset the twist and swing rotation of the target
  133. public void ResetRotation() {
  134. if (pivot != null) pivot.localRotation = defaultLocalRotation;
  135. }
  136. // Rotate this target towards a position
  137. public void RotateTo(Transform bone) {
  138. if (pivot == null) return;
  139. if (pivot != lastPivot) {
  140. defaultLocalRotation = pivot.localRotation;
  141. lastPivot = pivot;
  142. }
  143. // Rotate to the default local rotation
  144. pivot.localRotation = defaultLocalRotation;
  145. switch (rotationMode)
  146. {
  147. case RotationMode.TwoDOF:
  148. // Twisting around the twist axis
  149. if (twistWeight > 0f)
  150. {
  151. Vector3 targetTangent = transform.position - pivot.position;
  152. Vector3 n = pivot.rotation * twistAxis;
  153. Vector3 normal = n;
  154. Vector3.OrthoNormalize(ref normal, ref targetTangent);
  155. normal = n;
  156. Vector3 direction = bone.position - pivot.position;
  157. Vector3.OrthoNormalize(ref normal, ref direction);
  158. Quaternion q = QuaTools.FromToAroundAxis(targetTangent, direction, n);
  159. pivot.rotation = Quaternion.Lerp(Quaternion.identity, q, twistWeight) * pivot.rotation;
  160. }
  161. // Swinging freely
  162. if (swingWeight > 0f)
  163. {
  164. Quaternion s = Quaternion.FromToRotation(transform.position - pivot.position, bone.position - pivot.position);
  165. pivot.rotation = Quaternion.Lerp(Quaternion.identity, s, swingWeight) * pivot.rotation;
  166. }
  167. break;
  168. case RotationMode.ThreeDOF:
  169. // Free rotation around all axes
  170. if (threeDOFWeight <= 0f) break;
  171. Quaternion fromTo = QuaTools.FromToRotation(transform.rotation, bone.rotation);
  172. if (threeDOFWeight >= 1f)
  173. {
  174. pivot.rotation = fromTo * pivot.rotation;
  175. } else
  176. {
  177. pivot.rotation = Quaternion.Slerp(Quaternion.identity, fromTo, threeDOFWeight) * pivot.rotation;
  178. }
  179. break;
  180. }
  181. }
  182. }
  183. }