- Home /
How to make a 2D polygon collider from a mesh
I have a grid of Tiles that are under one chunk gameobject and each tile is a small square mesh. I was wondering how to generate a 2d polygon collider from this 3d mesh on only the dark tiles. I can separate the dark and light tiles into 2 meshes if need be.
Answer by Starleg2 · Jun 01, 2018 at 04:18 PM
After spending a huge amount of time, I finally found the solution to the collide generation
void MakeCollisions()
{
List<Edge> edges = new List<Edge>();
edges = GetEdges(meshCollision.triangles);
outsideEdges = FindBoundary(edges, meshCollision.vertices);
sortedOutsideEdges = SortEdges(outsideEdges);
print(sortedOutsideEdges.Count);
collisionPoints = convertEdgePathsToVector2Arrays(sortedOutsideEdges);
PC2D.pathCount = collisionPoints.Length;
for (int i = 0; i < collisionPoints.Length; i++)
{
PC2D.SetPath(i, collisionPoints[i]);
}
}
public struct Edge
{
public int v1;
public int v2;
public int triangleIndex;
public Edge(int aV1, int aV2, int aIndex)
{
v1 = aV1;
v2 = aV2;
triangleIndex = aIndex;
}
}
public static List<Edge> GetEdges(int[] aIndices)
{
List<Edge> result = new List<Edge>();
for (int i = 0; i < aIndices.Length; i += 3)
{
int v1 = aIndices[i];
int v2 = aIndices[i + 1];
int v3 = aIndices[i + 2];
result.Add(new Edge(v1, v2, i));
result.Add(new Edge(v2, v3, i));
result.Add(new Edge(v3, v1, i));
}
return result;
}
public static List<Edge> FindBoundary(List<Edge> aEdges, Vector3[] verts)
{
List<Edge> result = new List<Edge>(aEdges);
for (int i = result.Count - 1; i > 0; i--)
{
for (int n = i - 1; n >= 0; n--)
{
if (verts[result[i].v1] == verts[result[n].v2] && verts[result[i].v2] == verts[result[n].v1])
{
result.RemoveAt(i);
result.RemoveAt(n);
i--;
break;
}
}
}
return result;
}
public List<List<Edge>> SortEdges(List<Edge> bEdges)
{
List<Edge> borderEdges = bEdges;
List<List<Edge>> paths = new List<List<Edge>>();
List<Edge> currentPath = new List<Edge>();
while (borderEdges.Count > 0)
{
currentPath.Add(borderEdges[0]);
borderEdges.RemoveAt(0);
makePath(currentPath, borderEdges);
paths.Add(currentPath);
currentPath = new List<Edge>();
print(borderEdges.Count);
}
return paths;
}
public void makePath(List<Edge> currentPath, List<Edge> borderEdges)
{
bool continuePath = true;
List<Vector3> verts = VerticiesCollide;
while (continuePath)
{
for (int i = 0; i < borderEdges.Count; i++)
{
if (verts[currentPath[currentPath.Count - 1].v2] == verts[borderEdges[i].v1] || verts[currentPath[currentPath.Count - 1].v1] == verts[borderEdges[i].v2])
{
currentPath.Add(borderEdges[i]);
borderEdges.RemoveAt(i);
continuePath = true;
break;
}
else
{
continuePath = false;
}
}
if (borderEdges.Count == 0)
{
continuePath = false;
}
}
}
public Vector2[][] convertEdgePathsToVector2Arrays(List<List<Edge>> edgePaths)
{
Vector2[][] collisionPoints = new Vector2[edgePaths.Count][];
for (int i = 0; i < edgePaths.Count; i++)
{
collisionPoints[i] = new Vector2[edgePaths[i].Count];
for (int j = 0; j < edgePaths[i].Count; j++)
{
collisionPoints[i][j] = VerticiesCollide[edgePaths[i][j].v1];
}
}
return collisionPoints;
}
Below all this code is about 350 lines commented out. Anyway if it doesn't work for you just message me
the answer involved using edges ins$$anonymous$$d of whole tiles and finding the boundary, then ordering the bounding edges, and finally turning the edges into points!
I know this is long shot since this is so old but what values are stored in VerticiesCollide?
edgePaths is a list of a list of Edge structs. Edge.v1 is the index of a vertex located in the VerticiesCollide array. Since collisionPoints is an 2D array of vector2s VerticesCollide must be an array of vector2s
That doesn't really make sense with this line: List<Vector3> verts = VerticiesCollide;
If you are still there, could you post the full source code?
Your answer
![](https://koobas.hobune.stream/wayback/20220612163612im_/https://answers.unity.com/themes/thub/images/avi.jpg)