LimbSolver2D.cs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System.Collections.Generic;
  2. using UnityEngine.Scripting.APIUpdating;
  3. namespace UnityEngine.U2D.IK
  4. {
  5. /// <summary>
  6. /// Component for 2D Limb IK.
  7. /// </summary>
  8. [MovedFrom("UnityEngine.Experimental.U2D.IK")]
  9. [Solver2DMenuAttribute("Limb")]
  10. public class LimbSolver2D : Solver2D
  11. {
  12. [SerializeField]
  13. private IKChain2D m_Chain = new IKChain2D();
  14. [SerializeField]
  15. private bool m_Flip;
  16. private Vector3[] m_Positions = new Vector3[3];
  17. private float[] m_Lengths = new float[2];
  18. private float[] m_Angles = new float[2];
  19. /// <summary>
  20. /// Get Set for flip property.
  21. /// </summary>
  22. public bool flip
  23. {
  24. get { return m_Flip; }
  25. set { m_Flip = value; }
  26. }
  27. /// <summary>
  28. /// Override base class DoInitialize.
  29. /// </summary>
  30. protected override void DoInitialize()
  31. {
  32. m_Chain.transformCount = m_Chain.effector == null || IKUtility.GetAncestorCount(m_Chain.effector) < 2 ? 0 : 3;
  33. base.DoInitialize();
  34. }
  35. /// <summary>
  36. /// Override base class GetChainCount.
  37. /// </summary>
  38. /// <returns>Always returns 1.</returns>
  39. protected override int GetChainCount()
  40. {
  41. return 1;
  42. }
  43. /// <summary>
  44. /// Override base class GetChain.
  45. /// </summary>
  46. /// <param name="index">Index to query.</param>
  47. /// <returns>Returns IKChain2D for the Solver.</returns>
  48. public override IKChain2D GetChain(int index)
  49. {
  50. return m_Chain;
  51. }
  52. /// <summary>
  53. /// Override base class DoPrepare.
  54. /// </summary>
  55. protected override void DoPrepare()
  56. {
  57. var lengths = m_Chain.lengths;
  58. m_Positions[0] = m_Chain.transforms[0].position;
  59. m_Positions[1] = m_Chain.transforms[1].position;
  60. m_Positions[2] = m_Chain.transforms[2].position;
  61. m_Lengths[0] = lengths[0];
  62. m_Lengths[1] = lengths[1];
  63. }
  64. /// <summary>
  65. /// OVerride base class DoUpdateIK.
  66. /// </summary>
  67. /// <param name="effectorPositions">List of effector positions.</param>
  68. protected override void DoUpdateIK(List<Vector3> effectorPositions)
  69. {
  70. Vector3 effectorPosition = effectorPositions[0];
  71. Vector2 effectorLocalPosition2D = m_Chain.transforms[0].InverseTransformPoint(effectorPosition);
  72. effectorPosition = m_Chain.transforms[0].TransformPoint(effectorLocalPosition2D);
  73. if (effectorLocalPosition2D.sqrMagnitude > 0f && Limb.Solve(effectorPosition, m_Lengths, m_Positions, ref m_Angles))
  74. {
  75. float flipSign = flip ? -1f : 1f;
  76. m_Chain.transforms[0].localRotation *= Quaternion.FromToRotation(Vector3.right, effectorLocalPosition2D) * Quaternion.FromToRotation(m_Chain.transforms[1].localPosition, Vector3.right);
  77. m_Chain.transforms[0].localRotation *= Quaternion.AngleAxis(flipSign * m_Angles[0], Vector3.forward);
  78. m_Chain.transforms[1].localRotation *= Quaternion.FromToRotation(Vector3.right, m_Chain.transforms[1].InverseTransformPoint(effectorPosition)) * Quaternion.FromToRotation(m_Chain.transforms[2].localPosition, Vector3.right);
  79. }
  80. }
  81. }
  82. }