RotationLimitAngle.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace RootMotion.FinalIK {
  4. /// <summary>
  5. /// Simple angular rotation limit.
  6. /// </summary>
  7. [HelpURL("http://www.root-motion.com/finalikdox/html/page14.html")]
  8. [AddComponentMenu("Scripts/RootMotion.FinalIK/Rotation Limits/Rotation Limit Angle")]
  9. public class RotationLimitAngle : RotationLimit {
  10. // Open the User Manual URL
  11. [ContextMenu("User Manual")]
  12. private void OpenUserManual() {
  13. Application.OpenURL("http://www.root-motion.com/finalikdox/html/page14.html");
  14. }
  15. // Open the Script Reference URL
  16. [ContextMenu("Scrpt Reference")]
  17. private void OpenScriptReference() {
  18. Application.OpenURL("http://www.root-motion.com/finalikdox/html/class_root_motion_1_1_final_i_k_1_1_rotation_limit_angle.html");
  19. }
  20. // Link to the Final IK Google Group
  21. [ContextMenu("Support Group")]
  22. void SupportGroup() {
  23. Application.OpenURL("https://groups.google.com/forum/#!forum/final-ik");
  24. }
  25. // Link to the Final IK Asset Store thread in the Unity Community
  26. [ContextMenu("Asset Store Thread")]
  27. void ASThread() {
  28. Application.OpenURL("http://forum.unity3d.com/threads/final-ik-full-body-ik-aim-look-at-fabrik-ccd-ik-1-0-released.222685/");
  29. }
  30. #region Main Interface
  31. /// <summary>
  32. /// The swing limit.
  33. /// </summary>
  34. [Range(0f, 180f)] public float limit = 45;
  35. /// <summary>
  36. /// Limit of twist rotation around the main axis.
  37. /// </summary>
  38. [Range(0f, 180f)] public float twistLimit = 180;
  39. #endregion Main Interface
  40. /*
  41. * Limits the rotation in the local space of this instance's Transform.
  42. * */
  43. protected override Quaternion LimitRotation(Quaternion rotation) {
  44. // Subtracting off-limits swing
  45. Quaternion swing = LimitSwing(rotation);
  46. // Apply twist limits
  47. return LimitTwist(swing, axis, secondaryAxis, twistLimit);
  48. }
  49. /*
  50. * Apply swing limits
  51. * */
  52. private Quaternion LimitSwing(Quaternion rotation) {
  53. if (axis == Vector3.zero) return rotation; // Ignore with zero axes
  54. if (rotation == Quaternion.identity) return rotation; // Assuming initial rotation is in the reachable area
  55. if (limit >= 180) return rotation;
  56. Vector3 swingAxis = rotation * axis;
  57. // Get the limited swing axis
  58. Quaternion swingRotation = Quaternion.FromToRotation(axis, swingAxis);
  59. Quaternion limitedSwingRotation = Quaternion.RotateTowards(Quaternion.identity, swingRotation, limit);
  60. // Rotation from current(illegal) swing rotation to the limited(legal) swing rotation
  61. Quaternion toLimits = Quaternion.FromToRotation(swingAxis, limitedSwingRotation * axis);
  62. // Subtract the illegal rotation
  63. return toLimits * rotation;
  64. }
  65. }
  66. }