Created
October 30, 2018 13:20
-
-
Save drZool/cca7d5ad49f21e1d7edaca32714b4892 to your computer and use it in GitHub Desktop.
ColliderExtensions for checking overlapping colliders without using Unity physics.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using UnityEngine; | |
| using System.Collections; | |
| public static class ColliderExtensions | |
| { | |
| public static bool Overlaps (this BoxCollider box, SphereCollider sphere) | |
| { | |
| //Im sure there is a better way to do this, but it works for now. | |
| var sphereWorldCenter = sphere.transform.TransformPoint (sphere.center); | |
| var sphereWorldRadius = new Vector3 (sphere.transform.lossyScale.x * sphere.radius, 0, 0); | |
| // | |
| // Reset box to worldspace scale (1,1,1) | |
| // | |
| var originalBoxCenter = box.center; | |
| var originalBoxSize = box.size; | |
| var originalBoxScale = box.transform.localScale; | |
| box.center = Vector3.Scale (box.center, box.transform.lossyScale); | |
| box.size = Vector3.Scale (box.size, box.transform.lossyScale); | |
| box.transform.SetGlobalScale (Vector3.one); | |
| var sphereCenterInBoxSpace = box.transform.InverseTransformPoint (sphereWorldCenter) - box.center; | |
| var s = box.transform.InverseTransformVector (sphereWorldRadius).magnitude; | |
| float sphereRadiusInBoxSpace = s; | |
| var extents = box.size / 2; | |
| Vector3 distanceFromCenterOfBox = new Vector3 (Mathf.Abs (sphereCenterInBoxSpace.x), Mathf.Abs (sphereCenterInBoxSpace.y), Mathf.Abs (sphereCenterInBoxSpace.z)); | |
| bool result = false; | |
| //float sphereRadiusInBoxSpace = Mathf.Max (Mathf.Max (s.x, s.y), s.z); | |
| if (distanceFromCenterOfBox.x > sphereRadiusInBoxSpace + extents.x) | |
| goto defer; | |
| if (distanceFromCenterOfBox.z > sphereRadiusInBoxSpace + extents.z) | |
| goto defer; | |
| if (distanceFromCenterOfBox.y > sphereRadiusInBoxSpace + extents.y) | |
| goto defer; | |
| if (distanceFromCenterOfBox.x <= extents.x && distanceFromCenterOfBox.z <= extents.z && distanceFromCenterOfBox.y <= extents.y) { | |
| result = true; | |
| goto defer; | |
| } | |
| Vector3 closestPointOnBox = new Vector3 (Mathf.Clamp (sphereCenterInBoxSpace.x, -extents.x, extents.x), | |
| Mathf.Clamp (sphereCenterInBoxSpace.y, -extents.y, extents.y), | |
| Mathf.Clamp (sphereCenterInBoxSpace.z, -extents.z, extents.z)); | |
| var distVector = closestPointOnBox - sphereCenterInBoxSpace; | |
| result = (distVector.sqrMagnitude < sphereRadiusInBoxSpace * sphereRadiusInBoxSpace); | |
| defer: | |
| //Restore box scale | |
| box.center = originalBoxCenter; | |
| box.size = originalBoxSize; | |
| box.transform.localScale = originalBoxScale; | |
| return result; | |
| } | |
| public static bool Overlaps (this SphereCollider sphere, BoxCollider box) | |
| { | |
| return box.Overlaps (sphere); | |
| } | |
| public static bool OverlapsDebug (this BoxCollider box, SphereCollider sphere, out Vector3 spherePos, out float sphereRadius) | |
| { | |
| //Im sure there is a better way to do this, but it works for now. | |
| var sphereWorldCenter = sphere.transform.TransformPoint (sphere.center); | |
| var sphereWorldRadius = new Vector3 (sphere.transform.lossyScale.x * sphere.radius, 0, 0); | |
| // | |
| // Reset box to worldspace scale (1,1,1) | |
| // | |
| var originalBoxCenter = box.center; | |
| var originalBoxSize = box.size; | |
| var originalBoxScale = box.transform.localScale; | |
| box.center = Vector3.Scale (box.center, box.transform.lossyScale); | |
| box.size = Vector3.Scale (box.size, box.transform.lossyScale); | |
| box.transform.SetGlobalScale (Vector3.one); | |
| var sphereCenterInBoxSpace = box.transform.InverseTransformPoint (sphereWorldCenter) - box.center; | |
| var s = box.transform.InverseTransformVector (sphereWorldRadius).magnitude; | |
| float sphereRadiusInBoxSpace = s; | |
| var extents = box.size / 2; | |
| Vector3 distanceFromCenterOfBox = new Vector3 (Mathf.Abs (sphereCenterInBoxSpace.x), Mathf.Abs (sphereCenterInBoxSpace.y), Mathf.Abs (sphereCenterInBoxSpace.z)); | |
| bool result = false; | |
| //float sphereRadiusInBoxSpace = Mathf.Max (Mathf.Max (s.x, s.y), s.z); | |
| if (distanceFromCenterOfBox.x > sphereRadiusInBoxSpace + extents.x) | |
| goto defer; | |
| if (distanceFromCenterOfBox.z > sphereRadiusInBoxSpace + extents.z) | |
| goto defer; | |
| if (distanceFromCenterOfBox.y > sphereRadiusInBoxSpace + extents.y) | |
| goto defer; | |
| if (distanceFromCenterOfBox.x <= extents.x && distanceFromCenterOfBox.z <= extents.z && distanceFromCenterOfBox.y <= extents.y) { | |
| result = true; | |
| goto defer; | |
| } | |
| Vector3 closestPointOnBox = new Vector3 (Mathf.Clamp (sphereCenterInBoxSpace.x, -extents.x, extents.x), | |
| Mathf.Clamp (sphereCenterInBoxSpace.y, -extents.y, extents.y), | |
| Mathf.Clamp (sphereCenterInBoxSpace.z, -extents.z, extents.z)); | |
| var distVector = closestPointOnBox - sphereCenterInBoxSpace; | |
| result = (distVector.sqrMagnitude < sphereRadiusInBoxSpace * sphereRadiusInBoxSpace); | |
| defer: | |
| spherePos = box.transform.TransformPoint (sphereCenterInBoxSpace); | |
| var s2 = box.transform.TransformVector (new Vector3 (sphereRadiusInBoxSpace, 0, 0)); | |
| sphereRadius = s2.magnitude; | |
| //Restore box transforms | |
| box.center = originalBoxCenter; | |
| box.size = originalBoxSize; | |
| box.transform.localScale = originalBoxScale; | |
| return result; | |
| } | |
| public static void SetGlobalScale (this Transform transform, Vector3 globalScale) | |
| { | |
| transform.localScale = Vector3.one; | |
| var lossyScale = transform.lossyScale; | |
| transform.localScale = new Vector3 (globalScale.x / lossyScale.x, globalScale.y / lossyScale.y, globalScale.z / lossyScale.z); | |
| } | |
| public static bool OverlapsDebug (this SphereCollider sphere, BoxCollider box, out Vector3 spherePos, out float sphereRadius) | |
| { | |
| return box.OverlapsDebug (sphere, out spherePos, out sphereRadius); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment