I currently have a \"CreateMesh\" script that can be put as a component of an object with a Mesh Renderer, and a Mesh Filter, and a 2D mesh is created with a polygon collider in
The solution I've managed to find involves creating a regular polygon of n sides with a large value of n. I have a function called PolyMesh which creates a regular polygon mesh with n sides and a given radius.
Generating the vertices
For each vertex of a regular polygon with n sides the coordinates relative to the centre of the polygon are given by x = r*i*sin(θ)
and y = r*i*cos(θ)
so therefore x = r*i*sin(2π/2)
and y = r*i*cos(2π/2)
. Where i iterates from 0 to n-1. We can therefore have a list which has vertices assigned to it and then is converted to an array afterwards:
//verticies
List verticiesList = new List { };
float x;
float y;
for (int i = 0; i < n; i ++)
{
x = radius * Mathf.Sin((2 * Mathf.PI * i) / n);
y = radius * Mathf.Cos((2 * Mathf.PI * i) / n);
verticiesList.Add(new Vector3(x, y, 0f));
}
Vector3[] verticies = verticiesList.ToArray();
Generating the triangles
A given regular polygon of n sides can be split into n-2 triangles from the same point. So we can generate each triangle as follows:
//triangles
List trianglesList = new List { };
for(int i = 0; i < (n-2); i++)
{
trianglesList.Add(0);
trianglesList.Add(i+1);
trianglesList.Add(i+2);
}
int[] triangles = trianglesList.ToArray();
Generating the Normals
Since this is a 2d object we can have every normal as -Vector3.forward
like so:
//normals
List normalsList = new List { };
for (int i = 0; i < verticies.Length; i++)
{
normalsList.Add(-Vector3.forward);
}
Vector3[] normals = normalsList.ToArray();
Generating the collider
We could just use a circle collider with the same radius but in order to make this function work for a polygon of a smaller value of n we must use a PolygonCollider2D
. Since the vertices are already in order in the vertices array we can simply use them as the paths for our PolygonCollider2D
.
//polyCollider
polyCollider.pathCount = 1;
List pathList = new List { };
for (int i = 0; i < n; i++)
{
pathList.Add(new Vector2(verticies[i].x, verticies[i].y));
}
Vector2[] path = pathList.ToArray();
polyCollider.SetPath(0, path);
The complete code should look like this:
public PolygonCollider2D polyCollider;
void Start()
{
polyCollider = GetComponent();
}
void PolyMesh(float radius, int n)
{
MeshFilter mf = GetComponent();
Mesh mesh = new Mesh();
mf.mesh = mesh;
//verticies
List verticiesList = new List { };
float x;
float y;
for (int i = 0; i < n; i ++)
{
x = radius * Mathf.Sin((2 * Mathf.PI * i) / n);
y = radius * Mathf.Cos((2 * Mathf.PI * i) / n);
verticiesList.Add(new Vector3(x, y, 0f));
}
Vector3[] verticies = verticiesList.ToArray();
//triangles
List trianglesList = new List { };
for(int i = 0; i < (n-2); i++)
{
trianglesList.Add(0);
trianglesList.Add(i+1);
trianglesList.Add(i+2);
}
int[] triangles = trianglesList.ToArray();
//normals
List normalsList = new List { };
for (int i = 0; i < verticies.Length; i++)
{
normalsList.Add(-Vector3.forward);
}
Vector3[] normals = normalsList.ToArray();
//initialise
mesh.vertices = verticies;
mesh.triangles = triangles;
mesh.normals = normals;
//polyCollider
polyCollider.pathCount = 1;
List pathList = new List { };
for (int i = 0; i < n; i++)
{
pathList.Add(new Vector2(verticies[i].x, verticies[i].y));
}
Vector2[] path = pathList.ToArray();
polyCollider.SetPath(0, path);
}
An introduction to meshes