OBB collision detection in Unity?

I’m working on a rather special project using Unity where the user is able to move and rotate furnitures around a room. I manage their collision on my own because I found the physics-based approach way too unpredictable to my taste.

Each of my furniture objects have a rough bounding box that approximates their volume. While the user moves or rotates a furniture object, I test if the new desired position/orientation is valid by checking if it would intersect with another object.

Now that’s where problems start coming in. Since I’m not using non-kinematic rigidbodies on my objects, I cannot use the collision event notifications from the MonoBehaviour. I thought it wasn’t a big deal and that I could simply test for intersection with colliders close to the object the user is moving. It seems however that calling object.collider.Intersects(otherCollider) will perform a collision test using the AABB (axis-aligned bounding box) of the objects instead of their current OBB (oriented bounding box). It is an issue for me as the AABB test is a lot rougher than the OBB one, and when the objects are rotated in a particular way, I will get positive intersection test even though the two objects do not visually touch each other.

I have searched through the API for OBB intersection methods but could not find any. I have found that there are various AABB Bounds I can access (mesh.bounds, renderer.bounds, collider.bounds) that give me the object bounds in different spaces but this won’t help as it’s still just an AABB, not a OBB.

I’m curious is anyone has some tips/solutions on how I could achieve my goal of testing if the two furnitures are intersecting in an accurate way? Right now it seems that I’m gonna have to implement my own 2D OBB collision test using the separating axis theorem, but it feels like this is pretty common functionality that should already be present in the engine.

Thanks!

Are you sure your conclusion is right and that the problem is not related to the fact that your physical object to which you attached the collider does not move at all in the physical world representation due to the lack of a rigidbody?

Moving object that shall collide → rigidbody
Moving object that shall collide but not fire its events → rigidbody with collider marked as trigger
static object that gets collided against but will never move → does not need a rigidbody

Perhaps I’m missunderstanding the situation though?

and bounds etc are OBB (or local space AABB) actually.

What my test showed is that given two objects a b (each with a collider bbox but no rigidbody component), if I call a.collider.bounds.Intersects( b.collider.bounds ), I get the collision response of an AABB, not OBB. Also the documentation states that the Bounds class is AABB only. The documentation also says that collider.bounds gives the bounding box of the object in world space, but I think it only means it’s translated and scaled, not rotated (because of the fact it’s an AABB).

I do not want my furniture objects to be physically simulated (that is, have a non-kinematic rigidbody component) because the behaviour of the objects becomes very hard to predict and I want complete control over that for various reasons. So either I’m not quite grasping how I’m supposed to setup my furniture objects in unity to get the result I want (= full collision detection support but non-physically-simulated motion) or there is a gap somewhere in the feature set for my particular usecase. What do you think?

One thing I just don’t get is why Unity doesn’t allow us to receive the OnCollisionEnter event if we don’t have at least one rigidbody involved. What if I just want to use simple colliders?

The problem is its not the collider thats at fail here, but the bounds class, right. I’m think its used for View Frustum Culling internally (as early out test), so it wouldn’t be favorable for it to be able to support rotations from the performance point of view.

For that reason you won’t be able to avoid to use a rigidbody.
But I might be stupid here cause I also fail to see why you think you can’t use it.
Sure a rigidbody can cause a lot of headache, if you allow it to physically respond to stuff and carry on physical responses.
But nothing prevents you from disallowing it from doing exactly that, stuff like making it kinematic so its fully under your control (use rigidbody.position and rotation and position it in the fixedupdate function), similarly you can use the FreezeAll constraint for example
Also RigidBody offer the SweepTest to test collision into the future if you want to know hits before they happen instead of waiting for the hit with the callbacks.

Is this something thats not an option?

Its unhappy that you use the boxes, cause sphere and capsules both would have cast functions …

Using kinematic rigidbody still prevents me from receiving collision events (between two kinematic rigidbodies, as per Unity design). I also tried the rigidbody.SweepTest() and as far as I can tell, it won’t allow me to detect if Im colliding with something at my current position (if you know how to achieve that, please let me know!). It’s possible I haven’t implemented it correctly though so Im gonna try again with a very very small ray (to simulate no motion).

Most usual furnitures are boxy in shapes, so I’m kinda stuck with that. It’s wierd the Physics API doesn’t provide a box sweep though…

The box somehow came in place so “before that came in place” you would do the sweep test for that position and only move if the sweep didn’t hit.

Also due to the fact that you will likely want to visualize to the user that the move in place for that position is impossible, I think you might normally want to prefer using triggers over pure collision usage so you can visualize a “visual bounding box” with green - red for example (or hide / show the object or ghost unghost it depending on what you prefer).

I already tried the SweetTest() approach you described above. It detected that my dragged object entered another object fine, but once I was “inside” that object, I would not get positive collision anymore. So it’s not working out too good for my use-case either.

Your suggestion to use a trigger might work out. I’ve just checked the collision matrix in unity documentation and it seems to support sending trigger message between a Kinematic Rigidbody Collider and a Kinematic Rigidbody Trigger. I could use the trigger events to set a “isColliding” flag ON/OFF on my object while it’s being dragged, and use that in my dragging script.

I’ll let you know how it goes. Thanks for your help Dremora, you’re always the one guy answering my questions :slight_smile:

Ok, the trigger method worked perfect! I’ve create a small CollisionCache script that I put on my furniture objects. The CollisionCache script listens to the OnTriggerEnter() and OnTriggerLeave() events to maintain an internal list of the objects it’s currently colliding with. It exposes a IsColliding property that returns whether it’s currently colliding with something or not.

When I start dragging a furniture, I set its collider.isTrigger flag to true, and turn it off again at the end of the operation. Works really well.