- Home /
How do I check that a trigger collider is *completely* nested within another trigger collider?
I have a hierarchy of trigger colliders. Some colliders are entirely separate, others overlap to some degree, and some are completely contained within another collider, sometimes three or four levels deep. The colliders are either Sphere or Box colliders. The whole thing represents location zones of various sizes: islands, regions, towns, etc.
In order to determine where a given point lies, such as the position of the player, I need to find the innermost nested collider for that point. Physics.OverlapSphere gives me a list of colliders, but when examining them, I need to treat trigger colliders completely enclosed by another collider specially.
How can I determine whether one collider is completely nested within another?
Answer by Bampf · Apr 04, 2011 at 07:10 PM
Not quite sure I understand exactly what you are trying to accomplish, but...
The short answer is, since you are only using sphere and box colliders, given a pair of colliders A and B, you can test 6 points: the center of each face of the bounding box of A. If those points are all inside collider B, then A is inside B. (You can use the bounds' extents and the center of the bounding box to calculate the coordinates of those 6 points.) Oddly, there is no built-in Unity method to calculate if a point is inside a sphere collider- with a box collider you could use collider.bounds.Contains. But the sphere test is easy to write.
Assuming the geography doesn't change, you could build the zone heirarchy once as the game starts. It wouldn't be that hard to write something that walks all the colliders and tests them for enclosure. Each town could keep a link to its enclosing region(s), for example.
You might also consider manually assigning the colliders to layers. Each layer would represent a different zone type. This has a couple benefits. First, if you want to build the hierarchy you'd only have to test colliders against certain types. For example, you wouldn't need to test if an island was enclosed by a town; but you WOULD test the reverse case.
Secondly, depending on what you are trying to accomplish, you might be able to use the layers to avoid the need to store a hierarchy at all. For example, when calling OverlapSphere you could say that you are only interested in the Town layer. This would give you just the town colliders. Then repeat for other zone types as needed.
I'm well aware of the fact that it's always possible to test for enclosure using discrete geometrical tests, of course - but I was looking for a simple primitive, as the idea of such a test seems like something that would be built into the engine. I'm a bit surprised to find that Unity doesn't seem to be able to test for something as simple as enclosure of geometry.
Regarding the zone hierarchy: the tool I'm building is completely general and has an editor representation. The depth is arbitrary, and the topology might very well change, as some of the objects may be moving. The architecture I've designed handles all this efficiently and without hacks like OnTriggerStay et al - the only thing that needs to be implemented is that test for enclosure of one collider by another.
It shouldn't really come as a surprise that the Unity API doesn't include support for containment queries. There are many queries that might be of interest to developers (containment, closest points, etc.), but such queries are arguably outside the scope of what Unity offers and is intended to offer. In any case, it does sound like a custom solution might be most appropriate here; based on what you've posted at least, I'd probably just write code for whatever containment tests are needed and go from there.
Jesse, I agreed with you in principle, and thankfully the sphere and box tests are easy to write. But I sympathize with PeterB's frustration: it's not always obvious why Unity has one thing and not another. Even your examples of out-of-scope queries Unity implements in specific cases (Bounds.Contains; Rigidbody.ClosestPointOnBounds.) It just doesn't have them for all collider types. It's not an unreasonable idea.
Yeah, I know what you mean - Unity does include the occasional 'random' functionality that kind of makes it seem like it should include other related functionality as well. But, I always view these more as 'extras' than as an indication of what should be expected necessarily :)
Answer by marty 1 · May 05, 2011 at 03:19 PM
I think that if you have rigidbodies attached to each collider, you could also use ClosestPointOnBounds:
I.e.
var closestPointOnObjectA : Vector3 = rigidbody.ClosestPointOnBounds(objectBPosition); var closestPointOnObjectB : Vector3 = rigidbody.ClosestPointOnBounds(objectAPosition);
Then just check the distance between these two points to see if they overlap.