MeshColliders colliding with themselves, or "covering" an object with box colliders?

This question has been solved.

I used box colliders along each edge to create a "border" of box colliders that were properly scaled, sized, and rotated to fit around the entire object.


I procedurally generate an object that I need to have collide with other objects like it. Mesh Colliders unfortunately won't work in this instance because mesh colliders don't collide with other mesh colliders. I can't use convex mesh colliders because the objects I procedurally generate are convex some of the time.

So my question is... is there some script that can "cover" an object with box colliders? Or is there some way to make my mesh colliders collide with one another?

If not... is there a way I could manually place a collider given a set of four or eight points?

EDIT: People seem to be confused. Here's what I'm talking about.

alt text

This is an example of an object the user could create. It could look like this, it could be more complex than this, or it could be a simple circle. Even though it looks 3D, it's not. It's flat, it's just been extruded by 1 unit. (My UV coordinates are screwed up, which is why you get weird shading like that, but we'll save that for another question.)

Now... what I want is for this object to collide with other objects just like it (they could be equally as weird, big, or small. But they ONLY need to collide on the EDGES. The faces of the objects don't come into contact at all!

alt text

Wherever a red diamond appears is where I'd like a collider of some sort to be placed. You'll notice the segments are rectangular, however they can be of varying length and rotation.

Given a set of points along an extruded 2D mesh, this script will cover the "edge" with thin box colliders.

Vertices is your vertex array of points. Since my mesh has two sets of nearly identical points (one set for the front face, one set for the back), I only loop through halfway.

g is the parent object.

for (int i = 0; i < Vertices.Count / 2; i++)
{
    int j;
    if (i + 1 >= Vertices.Count / 2)
    {
        j = 0;
    }
    else
    {
        j = i + 1;
    }
    Vector3 center = new Vector3(((Vertices_.x + Vertices[j].x) / 2), ((Vertices*.y + Vertices[j].y) / 2), 0);*_
 <em>_float Ydiff = Vertices*.y - Vertices[j].y;*_</em>
 <em><em>_float Xdiff = Vertices*.x - Vertices[j].x;*_</em></em>
 <em><em><em>_float rotationAngle = Mathf.Atan2(Ydiff, Xdiff) * Mathf.Rad2Deg;_</em></em></em>
 <em><em>_*GameObject tc = new GameObject();*_</em></em>
 <em><em>_*tc.transform.position = center;*_</em></em>
 <em><em>_*tc.transform.eulerAngles = new Vector3(0, 0, rotationAngle);*_</em></em>
 <em><em>_*tc.transform.parent = g.transform;*_</em></em>
 <em><em>_*BoxCollider bc = tc.AddComponent(typeof(BoxCollider)) as BoxCollider;*_</em></em>
 <em><em><em>_bc.size = new Vector3((Vertices *- Vertices[j]).magnitude, 0.1f, 2);*_</em></em></em>
<em><em><em>_*}*_</em></em></em>
<em><em><em>_*```*_</em></em></em>

The easiest way to do this is probably to use child objects. These can be rotated and positioned to get your box colliders exactly where you need them.

This is a bit of a round about way but... You can create an empty game object with a box collider in it and put it in a prefab, then you can instantiate the prefab and adjust it's scale and parent it to your shape, this will give you lots of long thin colliders you can place between each point on your shape. Might be easier to place if you make the top corner or your collider at the origin point of the prefab, then you can instantiate the prefab at a point in your shape and then rotate it towards the next point in your shape and the multiply the scale of the prefab to match the distance to the next point.

I'll first point out that sphere colliders are probably going to be easier to work with, at least to start with. It's easy, given a set of points, to calculate a bounding sphere.

I'll also mention something which you may already know, which is that there isn't a unique solution to the problem. So you'll have to balance efficiency vs accuracy.

[Edit]I've seen your updated information. I'm still a bit curious about the mesh generation step: how that works could help us. But leaving that aside for now...

Possibly the easiest method to visualize and debug will be a recursive algorithm. You'll need to know how to do two things: 1. generate the minimum bounding axis-aligned box for a set of points. (Actually doesn't have to be the minimum, but that would be more efficient.) 2. given a box, sub-divide it into 4 quarters (we're keeping the depth axis 1 unit deep, so we only need to subdivide the X and Y axis.)

If either of these substeps gives you pause, let me know and I'll drill down. Assuming you have those steps down, the algorithm is: 1) Create the starting box, a minimum axis-aligned bounding box for all points in the mesh. 2) Subdivide into 4 smaller boxes, and call the following function Subdivide(). Subdivide: - if box is empty, return - if box contains points and is "small enough" then make a box collider of this size at this position. (Axis aligned, so no need to rotate it.) - else subdivide into four smaller boxes, call Subdivide on each one

Advantages: This isn't hard to write Since the user presumably is drawing with tools you give them, you may already have some idea how small the child colliders need to be. Child colliders don't overlap.

Disadvantages: Uses square shapes all the way down. Inefficient coverage depending on the object's shape, could require a lot of boxes to be really accurate.

[Edit 2] Of course, as soon as I left the computer I realized some important things about what I wrote earlier.

  1. It really doesn't have to be recursive. If you know the smallest box size, you can simply generate a full array of them at the beginning, keeping only the ones that are inside the mesh. This would work well with the next two points below.

  2. You have mentioned a few times being interested in the edges. If you truly aren't interested in the interior (though if the objects move at all quickly that would not be safe) you can simply throw out any box colliders that are surrounded by colliders on all 4 sides.

  3. Whether or not you do #2, you can merge adjacent boxes to greatly reduce the # of colliders. Easiest would be to do this in one direction. So if a box collider is present and would also have one to the right, just scale the first box collider to make it wider.

This will leave you will a series of strips, long thin box colliders that cover your objects.

This is a huge improvement over what I first suggested, but its still an approximation that may or may not suit your needs.

Hope this helps a little.

I doubt box colliders would work except for certain shapes. i.e., I don't think that would be feasible for any arbitrary shape, because some of the box corners would extend over the edges.

You might have some luck searching for "convex mesh decomposition". That way you can have several convex mesh colliders as children, which would make up one concave mesh collider that would still be able to collide with others.

If the math for that is too much (it's way beyond me), a simple solution would be to make one convex mesh collider out of each extruded triangle. See here for an example...the smaller shape is made of 3 convex mesh colliders, the larger shape has 4, and they collide nicely. Since you already have the triangles needed for the mesh, generating the colliders automatically would be relatively easy. (The example was made manually, sorry, I have no code. ;) )

Naturally you end up with more colliders than you technically "need" this way, but unless the shapes are massively complex or you have a lot of them in motion at once, I doubt that's really an issue.