Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by pateras · Dec 19, 2013 at 07:39 PM · collisionboundsintersection

What's the best/easiest way to do something like Bounds.Intersects but accounting for rotation?

I need to compare two cuboid volumes to see if they will overlap, but I need to take rotation into consideration. I also need to do this immediately, so I can't just use OnTriggerEnter or OnCollisionEnter, which would require waiting for a physics update. I was using Bounds.Intersect for this, and it worked great, but it can't handle rotation.

Is there a way to do this without having to do a lot of math by hand? And if not, can anyone recommend a particular approach?

Thank you.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Statement · Dec 19, 2013 at 07:51 PM 0
Share

I can't think of an out of the box solution. Consider looking for a third party library to avoid reinventing the whell. This should be a recurring pattern for developers to solve so I would be surprised if a little searching wouldn't find you a usable .NET implementation.

avatar image Statement · Dec 19, 2013 at 07:53 PM 0
Share

(Out of curiosity, to add a little meat to the question; what specific scenario do you have right now, where you must control the ti$$anonymous$$g of collision detection?)

avatar image pateras · Dec 19, 2013 at 07:56 PM 0
Share

I'm trying to find a free space for an object that is entering the world. I don't want the complexity of maintaining a state to span a physics update, as well as the fact that dozens, possibly hundreds, of objects could be blocking the way. So relying on the collision events might mean my object doesn't get spawned for a second or two.

1 Reply

· Add your reply
  • Sort: 
avatar image
2

Answer by Jessy · Dec 21, 2013 at 09:39 PM

This is easy to use if you use mesh.bounds (on a cube), because that's in local space.

Please let me know if you profile, and obtain a performance comparison with and without the "ContainsAny" line.

 namespace UnityEngine
 {
     using System;
     using System.Collections.Generic;
     using System.Linq;
     
     public static class BoundsExtensions
     {
         /// <param name="transform1">Transform of the Game Object associated with bounds1</param>
         /// <param name="transform2">Transform of the Game Object associated with bounds12</param>
         public static bool Intersects(this Bounds bounds1, Bounds bounds2, Transform transform1, Transform transform2)
         {
             Vector3[] bounds1Points = transform2.InverseTransformPoints(bounds1.EnumeratePoints(), transform1).ToArray();
             Vector3[] bounds2Points = transform1.InverseTransformPoints(bounds2.EnumeratePoints(), transform2).ToArray();
 
             // This is redundant, because this will return true in a subset of cases 
             // with edge intersections, but Unity's methods are not in C# and might be faster.
             // Requires profiling.
             if ( bounds1.ContainsAny(bounds2Points) || bounds2.ContainsAny(bounds1Points) )
                return true;
 
             Func<Vector3, Vector3, Bounds, bool> edgeIntersectsBounds = (point1, point2, bounds) =>
             {
                 Ray ray = new Ray(point1, point2 - point1);
                 if ( !bounds.IntersectRay(ray) )
                     return false;
                 
                 ray.origin = point2;
                 ray.direction = -ray.direction;
                 return bounds.IntersectRay(ray);
             };
 
             Func<Vector3[], Bounds, bool> pointsContainIntersectingEdge = (points, bounds) =>
             {
                 for (int i = 0; i < points.Length - 1; i++)
                     if (  points.Skip(i + 1).Any( p => edgeIntersectsBounds(points[i], p, bounds) )  )
                         return true;
 
                 return false;
             };
 
             return pointsContainIntersectingEdge(bounds2Points, bounds1) || pointsContainIntersectingEdge(bounds1Points, bounds2);
         }
         
         public static bool ContainsAny(this Bounds bounds, IEnumerable<Vector3> points)
         {
             return points.Any( p => bounds.Contains(p) );
         }
         
         public static IEnumerable<Vector3> EnumeratePoints(this Bounds bounds)
         {
             yield return bounds.min;
             yield return bounds.max;
             for (int axis = 0; axis < 3; axis++)
             {
                 Vector3 point = bounds.min;
                 point[axis] += bounds.size[axis];
                 yield return point;
                 
                 point = bounds.max;
                 point[axis] -= bounds.size[axis];
                 yield return point;
             }
         }
     }
 }

 namespace UnityEngine
 {    
     using System.Collections.Generic;
     using System.Linq;
     
     public static class TransformExtensions
     {
         /// <summary>
         /// from local to world space
         /// </summary>
         public static IEnumerable<Vector3> TransformPoints(this Transform transform, IEnumerable<Vector3> points)
         {
             return points.Select( p => transform.TransformPoint(p) );
         }
     
         /// <summary>
         /// from world to local space
         /// </summary>
         public static IEnumerable<Vector3> InverseTransformPoints(this Transform transform, IEnumerable<Vector3> points)
         {
             return points.Select( p => transform.InverseTransformPoint(p) );
         }
         
         /// <summary>
         /// Puts points from another Transform's local space into this one's.
         /// </summary>
         public static IEnumerable<Vector3> InverseTransformPoints(this Transform transform, IEnumerable<Vector3> points, Transform otherTransform)
         {
             return transform.InverseTransformPoints( otherTransform.TransformPoints(points) );
         }
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Problem with getting colliding objects 3 Answers

Check if mesh.bounds intersect a plane 1 Answer

Applying the Bounds class to a Sphere without using the Collision class 1 Answer

How to detect intersection in meshes? 0 Answers

Get coordonates of a ray in a bounding box? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges