So, I make a mesh at runtime but my normals are messed up all the time, and they change on every mesh? How would you go about making them point outwards? there can be strange shapes to that are not convex.

Pick a point in space that is “inside” and point the normal away from that.

You can take the cross product of the 3 vertices and use that as the basis for the triangle’s normal and then average adjacent triangles for shared vertices (assuming you have shared vertices)

Assuming a triangle made up of points A, B, C the cross product would be (B - A) x (C - A)

Note that if you’re winding order is incorrect your normal will face into the mesh instead of out of - in which case you should flip the order of B and C so the triangle is A, C, B instead.

Is that how the inbuilt RecalculateNormals() works? I played around with the winding order ending up with them sometimes facing inwards sometimes outwards.

A bit old, but no point in making a new thread. I’m re visiting this problem and am wondering if anyone has any ideas on what is with this? This is the code that I’m making my mesh with:

```
Mesh CreateMesh()
{
// convert polygon to triangles
poly = linePoints.ToArray();
Triangulator triangulator = new Triangulator(poly);
tris = triangulator.Triangulate();
m = new Mesh();
vertices = new Vector3[poly.Length*2];
for(int i=0;i<poly.Length;i++)
{
vertices[i].x = poly[i].x;
vertices[i].z = poly[i].z;
vertices[i].y = 10; // front vertex
vertices[i+poly.Length].x = poly[i].x;
vertices[i+poly.Length].z = poly[i].z;
vertices[i+poly.Length].y = -10; // back vertex
//vertices[i].y = 10;
//vertices[i+poly.Length].y = -10;
}
triangles = new int[tris.Length*2+poly.Length*6];
count_tris = 0;
for(int i=0;i<tris.Length;i+=3)
{
triangles[i] = tris[i];
triangles[i+1] = tris[i+1];
triangles[i+2] = tris[i+2];
} // front vertices
count_tris+=tris.Length;
for(int i=0;i<tris.Length;i+=3)
{
triangles[count_tris+i] = tris[i+2]+poly.Length;
triangles[count_tris+i+1] = tris[i+1]+poly.Length;
triangles[count_tris+i+2] = tris[i]+poly.Length;
} // back vertices
count_tris+=tris.Length;
for(int i=0;i<poly.Length;i++)
{
// triangles around the perimeter of the object
int n = (i+1)%poly.Length;
triangles[count_tris] = i;
triangles[count_tris+1] = i + poly.Length;//1
triangles[count_tris+5] = n; //5
triangles[count_tris+2] = n; //2
triangles[count_tris+4] = n + poly.Length;//4
triangles[count_tris+3] = i + poly.Length;//3
count_tris += 6;
}
m.vertices = vertices;
m.triangles = triangles;
m.Optimize();
m.RecalculateNormals();
Vector3[] normals = m.normals;
m.RecalculateBounds();
// m.Optimize();
meshCollider = sellectionHolder.AddComponent(typeof(MeshCollider)) as MeshCollider;
meshCollider.sharedMesh = m;
meshCollider.isTrigger = true;
meshCollider.convex = true;
sellectionHolder.tag = "Sellection";
rigid = sellectionHolder.AddComponent(typeof(Rigidbody)) as Rigidbody;
rigid.isKinematic = true;
sellectionHolder.transform.position += Vector3.zero;
meshCollider.convex = false;
filter = sellectionHolder.AddComponent(typeof(MeshFilter)) as MeshFilter;
filter.mesh = m;
meshRender = sellectionHolder.AddComponent(typeof(MeshRenderer)) as MeshRenderer;
meshRender.material = meshMat;
return m;
}
```