- Home /
Find all objects inside box collider
Hello, how to make table with all objects inside box collider which is trigger, alternatively find the nearest one? I tried something like this:
private void OnTriggerStay(Collider[] col)
but Collider[] does not work with OnTriggerStay
Answer by hexagonius · Apr 27, 2018 at 04:40 PM
If you want to know that at a certain point in time, just use an OverlapBox:
https://docs.unity3d.com/ScriptReference/Physics.OverlapBox.html
I need object with box collider because rotation and scale and position of collider are dynamic in my project and I need to see this box does it work as it should
Answer by Harinezumi · Apr 27, 2018 at 12:31 PM
This is not necessarily the best solution, but the simplest that comes to my mind: when a Collider enters a trigger that has this script, it is added to a list, when it exits, it is removed from the list. You can get the current list by calling GetColliders()
(just don't modify the contents):
public class ColliderContainer : MonoBehaviour {
private List<Collider> colliders = new List<Collider>();
public List<Collider> GetColliders () { return colliders; }
private void OnTriggerEnter (Collider other) {
if (!colliders.Contains(other)) { colliders.Add(other); }
}
private void OnTriggerExit (Collider other) {
colliders.Remove(other);
}
}
Yes, it works, I found this earlier but I thought there is simpler way
but what if this collider was turned off all this time, and when I turn it on, I already need this list?
OnTriggerStay is what you're looking for....just simply do this...
void OnTriggerStay(Collider other)
{
if(!colliders.Contains(other))
{
colliders.Add(other);
}
}
this will also check if the object is already in list so there shouldn't be duplication problems either....hope this helps
Answer by timothygao8710 · Mar 02, 2021 at 04:16 AM
Adding on the Harinezumi, a HashSet can be used rather than a list, which would yield a lower time complexity(make your code run faster). While the .Remove() and .Contains() method for List runs in O(N^2) and O(N) respectively, the .Remove() and .Contains() for HashSet are both O(1). This can make a huge difference if you're dealing with many objects. Also the code is simpler:
public class ColliderContainer : MonoBehaviour {
private HashSet<Collider> colliders = new HashSet<Collider>();
public HashSet<Collider> GetColliders () { return colliders; }
private void OnTriggerEnter (Collider other) {
colliders.Add(other); //hashset automatically handles duplicates
}
private void OnTriggerExit (Collider other) {
colliders.Remove(other);
}
}
Answer by hydrix · Feb 12 at 08:24 PM
First one tells whether Vector3 point resides within the BoxCollider.
Second one gives all Collider[] within the BoxCollider using a layer mask.
///<summary>
///returns true if the point is within our BoxCollider
///</summary>
public static bool IsWithinBoxBounds(Vector3 point, BoxCollider boxCollider) {
point = boxCollider.transform.InverseTransformPoint( point ) - boxCollider.center;
float halfX = (boxCollider.size.x * 0.5f);
float halfY = (boxCollider.size.y * 0.5f);
float halfZ = (boxCollider.size.z * 0.5f);
if( point.x < halfX && point.x > -halfX &&
point.y < halfY && point.y > -halfY &&
point.z < halfZ && point.z > -halfZ )
return true;
else
return false;
} //end func IsWithinBoxBounds
///<summary>
///returns all colliders within BoxCollider
///</summary>
public static Collider[] BoxColliderOverlaps(BoxCollider target, int layerMask, bool hitTriggers) {
return Physics.OverlapBox(target.transform.position + target.center, target.size * 0.5f, target.transform.rotation, layerMask, hitTriggers ? QueryTriggerInteraction.Collide : QueryTriggerInteraction.Ignore);
} //end func BoxColliderOverlaps