暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System;
  2. using UnityEngine.Scripting.APIUpdating;
  3. using UnityEngine.Serialization;
  4. namespace UnityEngine.U2D.IK
  5. {
  6. /// <summary>
  7. /// Class for storing data for a 2D IK Chain.
  8. /// </summary>
  9. [MovedFrom("UnityEngine.Experimental.U2D.IK")]
  10. [Serializable]
  11. public class IKChain2D
  12. {
  13. [SerializeField]
  14. [FormerlySerializedAs("m_Target")]
  15. Transform m_EffectorTransform;
  16. [SerializeField]
  17. [FormerlySerializedAs("m_Effector")]
  18. Transform m_TargetTransform;
  19. [SerializeField]
  20. int m_TransformCount;
  21. [SerializeField]
  22. Transform[] m_Transforms;
  23. [SerializeField]
  24. Quaternion[] m_DefaultLocalRotations;
  25. [SerializeField]
  26. Quaternion[] m_StoredLocalRotations;
  27. /// <summary>
  28. /// Lengths of IK Chain.
  29. /// </summary>
  30. /// <returns>Array of lengths in the IK Chain.</returns>
  31. protected float[] m_Lengths;
  32. /// <summary>
  33. /// Get and set the transform used as the IK Effector.
  34. /// </summary>
  35. public Transform effector
  36. {
  37. get => m_EffectorTransform;
  38. set => m_EffectorTransform = value;
  39. }
  40. /// <summary>
  41. /// Get and set the transform used as the IK Target.
  42. /// </summary>
  43. public Transform target
  44. {
  45. get => m_TargetTransform;
  46. set => m_TargetTransform = value;
  47. }
  48. /// <summary>
  49. /// Get the transforms that are used in the IK Chain.
  50. /// </summary>
  51. public Transform[] transforms => m_Transforms;
  52. /// <summary>
  53. /// Get the root transform for the IK Chain.
  54. /// </summary>
  55. public Transform rootTransform
  56. {
  57. get
  58. {
  59. if (m_Transforms != null && transformCount > 0 && m_Transforms.Length == transformCount)
  60. return m_Transforms[0];
  61. return null;
  62. }
  63. }
  64. Transform lastTransform
  65. {
  66. get
  67. {
  68. if (m_Transforms != null && transformCount > 0 && m_Transforms.Length == transformCount)
  69. return m_Transforms[transformCount - 1];
  70. return null;
  71. }
  72. }
  73. /// <summary>
  74. /// Get and Set the number of transforms in the IK Chain.
  75. /// </summary>
  76. public int transformCount
  77. {
  78. get => m_TransformCount;
  79. set => m_TransformCount = Mathf.Max(0, value);
  80. }
  81. /// <summary>
  82. /// Returns true if the IK Chain is valid. False otherwise.
  83. /// </summary>
  84. public bool isValid => Validate();
  85. /// <summary>
  86. /// Gets the length of the IK Chain.
  87. /// </summary>
  88. public float[] lengths
  89. {
  90. get
  91. {
  92. if (isValid)
  93. {
  94. PrepareLengths();
  95. return m_Lengths;
  96. }
  97. return null;
  98. }
  99. }
  100. bool Validate()
  101. {
  102. if (effector == null)
  103. return false;
  104. if (transformCount == 0)
  105. return false;
  106. if (m_Transforms == null || m_Transforms.Length != transformCount)
  107. return false;
  108. if (m_DefaultLocalRotations == null || m_DefaultLocalRotations.Length != transformCount)
  109. return false;
  110. if (m_StoredLocalRotations == null || m_StoredLocalRotations.Length != transformCount)
  111. return false;
  112. if (rootTransform == null)
  113. return false;
  114. if (lastTransform != effector)
  115. return false;
  116. return !target || !IKUtility.IsDescendentOf(target, rootTransform);
  117. }
  118. /// <summary>
  119. /// Initialize the IK Chain.
  120. /// </summary>
  121. public void Initialize()
  122. {
  123. if (effector == null || transformCount == 0 || IKUtility.GetAncestorCount(effector) < transformCount - 1)
  124. return;
  125. m_Transforms = new Transform[transformCount];
  126. m_DefaultLocalRotations = new Quaternion[transformCount];
  127. m_StoredLocalRotations = new Quaternion[transformCount];
  128. var currentTransform = effector;
  129. var index = transformCount - 1;
  130. while (currentTransform && index >= 0)
  131. {
  132. m_Transforms[index] = currentTransform;
  133. m_DefaultLocalRotations[index] = currentTransform.localRotation;
  134. currentTransform = currentTransform.parent;
  135. --index;
  136. }
  137. }
  138. void PrepareLengths()
  139. {
  140. var currentTransform = effector;
  141. var index = transformCount - 1;
  142. if (m_Lengths == null || m_Lengths.Length != transformCount - 1)
  143. m_Lengths = new float[transformCount - 1];
  144. while (currentTransform && index >= 0)
  145. {
  146. if (currentTransform.parent && index > 0)
  147. m_Lengths[index - 1] = (currentTransform.position - currentTransform.parent.position).magnitude;
  148. currentTransform = currentTransform.parent;
  149. --index;
  150. }
  151. }
  152. /// <summary>
  153. /// Restores the IK Chain to it's default pose.
  154. /// </summary>
  155. /// <param name="targetRotationIsConstrained">True to constrain the target rotation. False otherwise.</param>
  156. public void RestoreDefaultPose(bool targetRotationIsConstrained)
  157. {
  158. var count = targetRotationIsConstrained ? transformCount : transformCount - 1;
  159. for (var i = 0; i < count; ++i)
  160. m_Transforms[i].localRotation = m_DefaultLocalRotations[i];
  161. }
  162. /// <summary>
  163. /// Explicitly stores the local rotation.
  164. /// </summary>
  165. public void StoreLocalRotations()
  166. {
  167. for (var i = 0; i < m_Transforms.Length; ++i)
  168. m_StoredLocalRotations[i] = m_Transforms[i].localRotation;
  169. }
  170. /// <summary>
  171. /// Blend between Forward Kinematics and Inverse Kinematics.
  172. /// </summary>
  173. /// <param name="finalWeight">Weight for blend</param>
  174. /// <param name="targetRotationIsConstrained">True to constrain target rotation. False otherwise.</param>
  175. public void BlendFkToIk(float finalWeight, bool targetRotationIsConstrained)
  176. {
  177. var count = targetRotationIsConstrained ? transformCount : transformCount - 1;
  178. for (var i = 0; i < count; ++i)
  179. m_Transforms[i].localRotation = Quaternion.Slerp(m_StoredLocalRotations[i], m_Transforms[i].localRotation, finalWeight);
  180. }
  181. }
  182. }