using System; using UnityEngine; namespace GameKit.Dependencies.Utilities { public static class ColliderExtensions { public static void GetBoxOverlapParams(this BoxCollider boxCollider, out Vector3 center, out Vector3 halfExtents) { Transform cachedTransform = boxCollider.transform; // DO NOT USE UNITY'S VECTOR OPERATIONS IN HOT PATHS, UNITY DOESN'T OPTIMISE THEM center = cachedTransform.TransformPoint(boxCollider.center); Vector3 lossyScale = cachedTransform.lossyScale; Vector3 size = boxCollider.size; float x = size.x * 0.5f * lossyScale.x; float y = size.y * 0.5f * lossyScale.y; float z = size.z * 0.5f * lossyScale.z; halfExtents = new(x, y, z); } public static void GetCapsuleCastParams(this CapsuleCollider capsuleCollider, out Vector3 point1, out Vector3 point2, out float radius) { Transform cachedTransform = capsuleCollider.transform; Vector3 lossyScale = cachedTransform.lossyScale; // Use System.Math instead of UnityEngine.Mathf because it's much faster. float absX = Math.Abs(lossyScale.x); float absY = Math.Abs(lossyScale.y); float absZ = Math.Abs(lossyScale.z); float height; Vector3 direction; switch (capsuleCollider.direction) { case 1: { radius = capsuleCollider.radius * Math.Max(absX, absZ); height = capsuleCollider.height * absY; direction = Vector3.up; break; } case 2: { radius = capsuleCollider.radius * Math.Max(absX, absY); height = capsuleCollider.height * absZ; direction = Vector3.forward; break; } default: { // Falling back to X is Unity's default behaviour. radius = capsuleCollider.radius * Math.Max(absY, absZ); height = capsuleCollider.height * absX; direction = Vector3.right; break; } } Vector3 center = cachedTransform.TransformPoint(capsuleCollider.center); Vector3 offset = height < radius * 2.0f ? Vector3.zero : cachedTransform.TransformDirection(direction * (height * 0.5f - radius)); // DO NOT USE UNITY'S VECTOR OPERATIONS IN HOT PATHS, UNITY DOESN'T OPTIMISE THEM float x1 = center.x + offset.x; float y1 = center.y + offset.y; float z1 = center.z + offset.z; float x2 = center.x - offset.x; float y2 = center.y - offset.y; float z2 = center.z - offset.z; point1 = new(x1, y1, z1); point2 = new(x2, y2, z2); } public static void GetSphereOverlapParams(this SphereCollider sphereCollider, out Vector3 center, out float radius) { Transform cachedTransform = sphereCollider.transform; center = cachedTransform.TransformPoint(sphereCollider.center); Vector3 lossyScale = cachedTransform.lossyScale; // Use System.Math instead of UnityEngine.Mathf because it's much faster. float x = Math.Abs(lossyScale.x); float y = Math.Abs(lossyScale.y); float z = Math.Abs(lossyScale.z); // Two calls of Math.Max are faster than a single Mathf.Max call because Math.Max doesn't allocate memory and doesn't use loops. radius = sphereCollider.radius * Math.Max(Math.Max(x, y), z); } } public static class Collider2DExtensions { public static void GetBox2DOverlapParams(this BoxCollider2D boxCollider, out Vector3 center, out Vector3 halfExtents) { Transform cachedTransform = boxCollider.transform; // DO NOT USE UNITY'S VECTOR OPERATIONS IN HOT PATHS, UNITY DOESN'T OPTIMISE THEM center = cachedTransform.TransformPoint(boxCollider.offset); Vector3 lossyScale = cachedTransform.lossyScale; Vector3 size = boxCollider.size; float x = size.x * 0.5f * lossyScale.x; float y = size.y * 0.5f * lossyScale.y; float z = size.z * 0.5f * lossyScale.z; halfExtents = new(x, y, z); } public static void GetCircleOverlapParams(this CircleCollider2D circleCollider, out Vector3 center, out float radius) { Transform cachedTransform = circleCollider.transform; Vector3 offset = new(circleCollider.offset.x, circleCollider.offset.y, circleCollider.transform.position.z); center = cachedTransform.TransformPoint(offset); Vector3 lossyScale = cachedTransform.lossyScale; // Use System.Math instead of UnityEngine.Mathf because it's much faster. float x = Math.Abs(lossyScale.x); float y = Math.Abs(lossyScale.y); float z = Math.Abs(lossyScale.z); // Two calls of Math.Max are faster than a single Mathf.Max call because Math.Max doesn't allocate memory and doesn't use loops. radius = circleCollider.radius * Math.Max(Math.Max(x, y), z); } } }