using UnityEngine; namespace FIMSpace { public class FImp_ColliderData_Capsule : FImp_ColliderData_Base { private Vector3 Top; private Vector3 Bottom; private Vector3 Direction; private float radius; private float scaleFactor; private float preRadius; public CapsuleCollider Capsule { get; private set; } public CapsuleCollider2D Capsule2D { get; private set; } public FImp_ColliderData_Capsule(CapsuleCollider collider) { Is2D = false; base.Transform = collider.transform; base.Collider = collider; base.Transform = collider.transform; Capsule = collider; base.ColliderType = EFColliderType.Capsule; CalculateCapsuleParameters(Capsule, ref Direction, ref radius, ref scaleFactor); RefreshColliderData(); } public FImp_ColliderData_Capsule(CapsuleCollider2D collider) { Is2D = true; base.Transform = collider.transform; base.Collider2D = collider; base.Transform = collider.transform; Capsule2D = collider; base.ColliderType = EFColliderType.Capsule; CalculateCapsuleParameters(Capsule2D, ref Direction, ref radius, ref scaleFactor); RefreshColliderData(); } public override void RefreshColliderData() { if (base.IsStatic) { return; } bool flag = false; if (!previousPosition.VIsSame(base.Transform.position)) { flag = true; } else if (!base.Transform.rotation.QIsSame(previousRotation)) { flag = true; } else if (!Is2D) { if (preRadius != Capsule.radius || !previousScale.VIsSame(base.Transform.lossyScale)) { CalculateCapsuleParameters(Capsule, ref Direction, ref radius, ref scaleFactor); } } else if (preRadius != GetCapsule2DRadius(Capsule2D) || !previousScale.VIsSame(base.Transform.lossyScale)) { CalculateCapsuleParameters(Capsule2D, ref Direction, ref radius, ref scaleFactor); } if (flag) { if (!Is2D) { GetCapsuleHeadsPositions(Capsule, ref Top, ref Bottom, Direction, radius, scaleFactor); } else { GetCapsuleHeadsPositions(Capsule2D, ref Top, ref Bottom, Direction, radius, scaleFactor); } } base.RefreshColliderData(); previousPosition = base.Transform.position; previousRotation = base.Transform.rotation; previousScale = base.Transform.lossyScale; if (!Is2D) { preRadius = Capsule.radius; } else { preRadius = GetCapsule2DRadius(Capsule2D); } } public override bool PushIfInside(ref Vector3 point, float pointRadius, Vector3 pointOffset) { return PushOutFromCapsuleCollider(pointRadius, ref point, Top, Bottom, radius, pointOffset, Is2D); } public static bool PushOutFromCapsuleCollider(CapsuleCollider capsule, float segmentColliderRadius, ref Vector3 pos, Vector3 segmentOffset) { Vector3 direction = Vector3.zero; float trueRadius = capsule.radius; float scalerFactor = 1f; CalculateCapsuleParameters(capsule, ref direction, ref trueRadius, ref scalerFactor); Vector3 upper = Vector3.zero; Vector3 bottom = Vector3.zero; GetCapsuleHeadsPositions(capsule, ref upper, ref bottom, direction, trueRadius, scalerFactor); return PushOutFromCapsuleCollider(segmentColliderRadius, ref pos, upper, bottom, trueRadius, segmentOffset); } public static bool PushOutFromCapsuleCollider(float segmentColliderRadius, ref Vector3 segmentPos, Vector3 capSphereCenter1, Vector3 capSphereCenter2, float capsuleRadius, Vector3 segmentOffset, bool is2D = false) { float num = capsuleRadius + segmentColliderRadius; Vector3 vector = capSphereCenter2 - capSphereCenter1; Vector3 vector2 = segmentPos + segmentOffset - capSphereCenter1; if (is2D) { vector.z = 0f; vector2.z = 0f; } float num2 = Vector3.Dot(vector2, vector); if (num2 <= 0f) { float sqrMagnitude = vector2.sqrMagnitude; if (sqrMagnitude > 0f && sqrMagnitude < num * num) { segmentPos = capSphereCenter1 - segmentOffset + vector2 * (num / Mathf.Sqrt(sqrMagnitude)); return true; } } else { float sqrMagnitude2 = vector.sqrMagnitude; if (num2 >= sqrMagnitude2) { vector2 = segmentPos + segmentOffset - capSphereCenter2; float sqrMagnitude3 = vector2.sqrMagnitude; if (sqrMagnitude3 > 0f && sqrMagnitude3 < num * num) { segmentPos = capSphereCenter2 - segmentOffset + vector2 * (num / Mathf.Sqrt(sqrMagnitude3)); return true; } } else if (sqrMagnitude2 > 0f) { vector2 -= vector * (num2 / sqrMagnitude2); float sqrMagnitude4 = vector2.sqrMagnitude; if (sqrMagnitude4 > 0f && sqrMagnitude4 < num * num) { float num3 = Mathf.Sqrt(sqrMagnitude4); segmentPos += vector2 * ((num - num3) / num3); return true; } } } return false; } protected static void CalculateCapsuleParameters(CapsuleCollider capsule, ref Vector3 direction, ref float trueRadius, ref float scalerFactor) { Transform transform = capsule.transform; float num; if (capsule.direction == 1) { direction = Vector3.up; scalerFactor = transform.lossyScale.y; num = ((transform.lossyScale.x > transform.lossyScale.z) ? transform.lossyScale.x : transform.lossyScale.z); } else if (capsule.direction == 0) { direction = Vector3.right; scalerFactor = transform.lossyScale.x; num = ((transform.lossyScale.y > transform.lossyScale.z) ? transform.lossyScale.y : transform.lossyScale.z); } else { direction = Vector3.forward; scalerFactor = transform.lossyScale.z; num = ((transform.lossyScale.y > transform.lossyScale.x) ? transform.lossyScale.y : transform.lossyScale.x); } trueRadius = capsule.radius * num; } private static float GetCapsule2DRadius(CapsuleCollider2D capsule) { if (capsule.direction == CapsuleDirection2D.Vertical) { return capsule.size.x / 2f; } return capsule.size.y / 2f; } private static float GetCapsule2DHeight(CapsuleCollider2D capsule) { if (capsule.direction == CapsuleDirection2D.Vertical) { return capsule.size.y / 2f; } return capsule.size.x / 2f; } protected static void CalculateCapsuleParameters(CapsuleCollider2D capsule, ref Vector3 direction, ref float trueRadius, ref float scalerFactor) { Transform transform = capsule.transform; if (capsule.direction == CapsuleDirection2D.Vertical) { direction = Vector3.up; scalerFactor = transform.lossyScale.y; float num = ((transform.lossyScale.x > transform.lossyScale.z) ? transform.lossyScale.x : transform.lossyScale.z); trueRadius = capsule.size.x / 2f * num; } else if (capsule.direction == CapsuleDirection2D.Horizontal) { direction = Vector3.right; scalerFactor = transform.lossyScale.x; float num = ((transform.lossyScale.y > transform.lossyScale.z) ? transform.lossyScale.y : transform.lossyScale.z); trueRadius = capsule.size.y / 2f * num; } } protected static void GetCapsuleHeadsPositions(CapsuleCollider capsule, ref Vector3 upper, ref Vector3 bottom, Vector3 direction, float radius, float scalerFactor) { Vector3 direction2 = direction * (capsule.height / 2f * scalerFactor - radius); upper = capsule.transform.position + capsule.transform.TransformDirection(direction2) + capsule.transform.TransformVector(capsule.center); Vector3 direction3 = -direction * (capsule.height / 2f * scalerFactor - radius); bottom = capsule.transform.position + capsule.transform.TransformDirection(direction3) + capsule.transform.TransformVector(capsule.center); } protected static void GetCapsuleHeadsPositions(CapsuleCollider2D capsule, ref Vector3 upper, ref Vector3 bottom, Vector3 direction, float radius, float scalerFactor) { Vector3 direction2 = direction * (GetCapsule2DHeight(capsule) * scalerFactor - radius); upper = capsule.transform.position + capsule.transform.TransformDirection(direction2) + capsule.transform.TransformVector(capsule.offset); upper.z = 0f; Vector3 direction3 = -direction * (GetCapsule2DHeight(capsule) * scalerFactor - radius); bottom = capsule.transform.position + capsule.transform.TransformDirection(direction3) + capsule.transform.TransformVector(capsule.offset); bottom.z = 0f; } } }