using System; using System.IO; using UnityEngine; [AddComponentMenu("Dynamic Bone/Dynamic Bone Collider")] public class DynamicBoneCollider : DynamicBoneColliderBase { public override string TypeName { get { return "dbc"; } } public float GetLossyScale() { return this.m_Radius * Mathf.Abs(base.transform.lossyScale.x); } public override void Serialize(BinaryWriter f_bw, int f_nVersion) { base.Serialize(f_bw, f_nVersion); f_bw.Write(this.m_Radius); f_bw.Write(this.m_Height); } public override void Deserialize(BinaryReader f_br, int f_nVersion, Transform f_trBodyBoneRoot) { base.Deserialize(f_br, f_nVersion, f_trBodyBoneRoot); this.m_Radius = f_br.ReadSingle(); this.m_Height = f_br.ReadSingle(); } private void OnValidate() { this.m_Radius = Mathf.Max(this.m_Radius, 0f); this.m_Height = Mathf.Max(this.m_Height, 0f); } public override bool Collide(ref Vector3 particlePosition, float particleRadius) { float num = this.m_Radius * Mathf.Abs(base.transform.lossyScale.x); float num2 = this.m_Height * 0.5f - this.m_Radius; if (num2 <= 0f) { if (this.m_Bound == DynamicBoneColliderBase.Bound.Outside) { return DynamicBoneCollider.OutsideSphere(ref particlePosition, particleRadius, base.transform.TransformPoint(this.m_Center), num); } return DynamicBoneCollider.InsideSphere(ref particlePosition, particleRadius, base.transform.TransformPoint(this.m_Center), num); } else { Vector3 center = this.m_Center; Vector3 center2 = this.m_Center; DynamicBoneColliderBase.Direction direction = this.m_Direction; if (direction != DynamicBoneColliderBase.Direction.X) { if (direction != DynamicBoneColliderBase.Direction.Y) { if (direction == DynamicBoneColliderBase.Direction.Z) { center.z -= num2; center2.z += num2; } } else { center.y -= num2; center2.y += num2; } } else { center.x -= num2; center2.x += num2; } if (this.m_Bound == DynamicBoneColliderBase.Bound.Outside) { return DynamicBoneCollider.OutsideCapsule(ref particlePosition, particleRadius, base.transform.TransformPoint(center), base.transform.TransformPoint(center2), num); } return DynamicBoneCollider.InsideCapsule(ref particlePosition, particleRadius, base.transform.TransformPoint(center), base.transform.TransformPoint(center2), num); } } private static bool OutsideSphere(ref Vector3 particlePosition, float particleRadius, Vector3 sphereCenter, float sphereRadius) { float num = sphereRadius + particleRadius; float num2 = num * num; Vector3 a = particlePosition - sphereCenter; float sqrMagnitude = a.sqrMagnitude; if (sqrMagnitude > 0f && sqrMagnitude < num2) { float num3 = Mathf.Sqrt(sqrMagnitude); particlePosition = sphereCenter + a * (num / num3); return true; } return false; } private static bool InsideSphere(ref Vector3 particlePosition, float particleRadius, Vector3 sphereCenter, float sphereRadius) { float num = sphereRadius - particleRadius; float num2 = num * num; Vector3 a = particlePosition - sphereCenter; float sqrMagnitude = a.sqrMagnitude; if (sqrMagnitude > num2) { float num3 = Mathf.Sqrt(sqrMagnitude); particlePosition = sphereCenter + a * (num / num3); return true; } return false; } private static bool OutsideCapsule(ref Vector3 particlePosition, float particleRadius, Vector3 capsuleP0, Vector3 capsuleP1, float capsuleRadius) { float num = capsuleRadius + particleRadius; float num2 = num * num; Vector3 vector = capsuleP1 - capsuleP0; Vector3 vector2 = particlePosition - capsuleP0; float num3 = Vector3.Dot(vector2, vector); if (num3 <= 0f) { float sqrMagnitude = vector2.sqrMagnitude; if (sqrMagnitude > 0f && sqrMagnitude < num2) { float num4 = Mathf.Sqrt(sqrMagnitude); particlePosition = capsuleP0 + vector2 * (num / num4); return true; } } else { float sqrMagnitude2 = vector.sqrMagnitude; if (num3 >= sqrMagnitude2) { vector2 = particlePosition - capsuleP1; float sqrMagnitude3 = vector2.sqrMagnitude; if (sqrMagnitude3 > 0f && sqrMagnitude3 < num2) { float num5 = Mathf.Sqrt(sqrMagnitude3); particlePosition = capsuleP1 + vector2 * (num / num5); return true; } } else if (sqrMagnitude2 > 0f) { num3 /= sqrMagnitude2; vector2 -= vector * num3; float sqrMagnitude4 = vector2.sqrMagnitude; if (sqrMagnitude4 > 0f && sqrMagnitude4 < num2) { float num6 = Mathf.Sqrt(sqrMagnitude4); particlePosition += vector2 * ((num - num6) / num6); return true; } } } return false; } private static bool InsideCapsule(ref Vector3 particlePosition, float particleRadius, Vector3 capsuleP0, Vector3 capsuleP1, float capsuleRadius) { float num = capsuleRadius - particleRadius; float num2 = num * num; Vector3 vector = capsuleP1 - capsuleP0; Vector3 vector2 = particlePosition - capsuleP0; float num3 = Vector3.Dot(vector2, vector); if (num3 <= 0f) { float sqrMagnitude = vector2.sqrMagnitude; if (sqrMagnitude > num2) { float num4 = Mathf.Sqrt(sqrMagnitude); particlePosition = capsuleP0 + vector2 * (num / num4); return true; } } else { float sqrMagnitude2 = vector.sqrMagnitude; if (num3 >= sqrMagnitude2) { vector2 = particlePosition - capsuleP1; float sqrMagnitude3 = vector2.sqrMagnitude; if (sqrMagnitude3 > num2) { float num5 = Mathf.Sqrt(sqrMagnitude3); particlePosition = capsuleP1 + vector2 * (num / num5); return true; } } else if (sqrMagnitude2 > 0f) { num3 /= sqrMagnitude2; vector2 -= vector * num3; float sqrMagnitude4 = vector2.sqrMagnitude; if (sqrMagnitude4 > num2) { float num6 = Mathf.Sqrt(sqrMagnitude4); particlePosition += vector2 * ((num - num6) / num6); return true; } } } return false; } [Tooltip("The radius of the sphere or capsule.")] public float m_Radius = 0.5f; [Tooltip("The height of the capsule.")] public float m_Height; }