源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
6.8 KiB

  1. using UnityEngine;
  2. [AddComponentMenu("Dynamic Bone/Dynamic Bone Collider")]
  3. public class DynamicBoneCollider : DynamicBoneColliderBase
  4. {
  5. #if UNITY_5
  6. [Tooltip("The radius of the sphere or capsule.")]
  7. #endif
  8. public float m_Radius = 0.5f;
  9. #if UNITY_5
  10. [Tooltip("The height of the capsule.")]
  11. #endif
  12. public float m_Height = 0;
  13. void OnValidate()
  14. {
  15. m_Radius = Mathf.Max(m_Radius, 0);
  16. m_Height = Mathf.Max(m_Height, 0);
  17. }
  18. public override void Collide(ref Vector3 particlePosition, float particleRadius)
  19. {
  20. float radius = m_Radius * Mathf.Abs(transform.lossyScale.x);
  21. float h = m_Height * 0.5f - m_Radius;
  22. if (h <= 0)
  23. {
  24. if (m_Bound == Bound.Outside)
  25. OutsideSphere(ref particlePosition, particleRadius, transform.TransformPoint(m_Center), radius);
  26. else
  27. InsideSphere(ref particlePosition, particleRadius, transform.TransformPoint(m_Center), radius);
  28. }
  29. else
  30. {
  31. Vector3 c0 = m_Center;
  32. Vector3 c1 = m_Center;
  33. switch (m_Direction)
  34. {
  35. case Direction.X:
  36. c0.x -= h;
  37. c1.x += h;
  38. break;
  39. case Direction.Y:
  40. c0.y -= h;
  41. c1.y += h;
  42. break;
  43. case Direction.Z:
  44. c0.z -= h;
  45. c1.z += h;
  46. break;
  47. }
  48. if (m_Bound == Bound.Outside)
  49. OutsideCapsule(ref particlePosition, particleRadius, transform.TransformPoint(c0), transform.TransformPoint(c1), radius);
  50. else
  51. InsideCapsule(ref particlePosition, particleRadius, transform.TransformPoint(c0), transform.TransformPoint(c1), radius);
  52. }
  53. }
  54. static void OutsideSphere(ref Vector3 particlePosition, float particleRadius, Vector3 sphereCenter, float sphereRadius)
  55. {
  56. float r = sphereRadius + particleRadius;
  57. float r2 = r * r;
  58. Vector3 d = particlePosition - sphereCenter;
  59. float len2 = d.sqrMagnitude;
  60. // if is inside sphere, project onto sphere surface
  61. if (len2 > 0 && len2 < r2)
  62. {
  63. float len = Mathf.Sqrt(len2);
  64. particlePosition = sphereCenter + d * (r / len);
  65. }
  66. }
  67. static void InsideSphere(ref Vector3 particlePosition, float particleRadius, Vector3 sphereCenter, float sphereRadius)
  68. {
  69. float r = sphereRadius - particleRadius;
  70. float r2 = r * r;
  71. Vector3 d = particlePosition - sphereCenter;
  72. float len2 = d.sqrMagnitude;
  73. // if is outside sphere, project onto sphere surface
  74. if (len2 > r2)
  75. {
  76. float len = Mathf.Sqrt(len2);
  77. particlePosition = sphereCenter + d * (r / len);
  78. }
  79. }
  80. static void OutsideCapsule(ref Vector3 particlePosition, float particleRadius, Vector3 capsuleP0, Vector3 capsuleP1, float capsuleRadius)
  81. {
  82. float r = capsuleRadius + particleRadius;
  83. float r2 = r * r;
  84. Vector3 dir = capsuleP1 - capsuleP0;
  85. Vector3 d = particlePosition - capsuleP0;
  86. float t = Vector3.Dot(d, dir);
  87. if (t <= 0)
  88. {
  89. // check sphere1
  90. float len2 = d.sqrMagnitude;
  91. if (len2 > 0 && len2 < r2)
  92. {
  93. float len = Mathf.Sqrt(len2);
  94. particlePosition = capsuleP0 + d * (r / len);
  95. }
  96. }
  97. else
  98. {
  99. float dl = dir.sqrMagnitude;
  100. if (t >= dl)
  101. {
  102. // check sphere2
  103. d = particlePosition - capsuleP1;
  104. float len2 = d.sqrMagnitude;
  105. if (len2 > 0 && len2 < r2)
  106. {
  107. float len = Mathf.Sqrt(len2);
  108. particlePosition = capsuleP1 + d * (r / len);
  109. }
  110. }
  111. else if (dl > 0)
  112. {
  113. // check cylinder
  114. t /= dl;
  115. d -= dir * t;
  116. float len2 = d.sqrMagnitude;
  117. if (len2 > 0 && len2 < r2)
  118. {
  119. float len = Mathf.Sqrt(len2);
  120. particlePosition += d * ((r - len) / len);
  121. }
  122. }
  123. }
  124. }
  125. static void InsideCapsule(ref Vector3 particlePosition, float particleRadius, Vector3 capsuleP0, Vector3 capsuleP1, float capsuleRadius)
  126. {
  127. float r = capsuleRadius - particleRadius;
  128. float r2 = r * r;
  129. Vector3 dir = capsuleP1 - capsuleP0;
  130. Vector3 d = particlePosition - capsuleP0;
  131. float t = Vector3.Dot(d, dir);
  132. if (t <= 0)
  133. {
  134. // check sphere1
  135. float len2 = d.sqrMagnitude;
  136. if (len2 > r2)
  137. {
  138. float len = Mathf.Sqrt(len2);
  139. particlePosition = capsuleP0 + d * (r / len);
  140. }
  141. }
  142. else
  143. {
  144. float dl = dir.sqrMagnitude;
  145. if (t >= dl)
  146. {
  147. // check sphere2
  148. d = particlePosition - capsuleP1;
  149. float len2 = d.sqrMagnitude;
  150. if (len2 > r2)
  151. {
  152. float len = Mathf.Sqrt(len2);
  153. particlePosition = capsuleP1 + d * (r / len);
  154. }
  155. }
  156. else if (dl > 0)
  157. {
  158. // check cylinder
  159. t /= dl;
  160. d -= dir * t;
  161. float len2 = d.sqrMagnitude;
  162. if (len2 > r2)
  163. {
  164. float len = Mathf.Sqrt(len2);
  165. particlePosition += d * ((r - len) / len);
  166. }
  167. }
  168. }
  169. }
  170. void OnDrawGizmosSelected()
  171. {
  172. if (!enabled)
  173. return;
  174. if (m_Bound == Bound.Outside)
  175. Gizmos.color = Color.yellow;
  176. else
  177. Gizmos.color = Color.magenta;
  178. float radius = m_Radius * Mathf.Abs(transform.lossyScale.x);
  179. float h = m_Height * 0.5f - m_Radius;
  180. if (h <= 0)
  181. {
  182. Gizmos.DrawWireSphere(transform.TransformPoint(m_Center), radius);
  183. }
  184. else
  185. {
  186. Vector3 c0 = m_Center;
  187. Vector3 c1 = m_Center;
  188. switch (m_Direction)
  189. {
  190. case Direction.X:
  191. c0.x -= h;
  192. c1.x += h;
  193. break;
  194. case Direction.Y:
  195. c0.y -= h;
  196. c1.y += h;
  197. break;
  198. case Direction.Z:
  199. c0.z -= h;
  200. c1.z += h;
  201. break;
  202. }
  203. Gizmos.DrawWireSphere(transform.TransformPoint(c0), radius);
  204. Gizmos.DrawWireSphere(transform.TransformPoint(c1), radius);
  205. }
  206. }
  207. }