Search Unity

Mesh creation by code not working

Discussion in 'Scripting' started by ashjack, Nov 19, 2017.

  1. ashjack

    ashjack

    Joined:
    Jun 9, 2013
    Posts:
    44
    'm trying to make a script that creates a random 2d polygon from triangles, but the code I'm currently using only results in a mess of angles and crossing lines. I've tried to make the code so that it picks points around the centre of the shape, and ordering the angles so that none should cross, but they do anyway.

    This is the kind of thing I want it to look like (minus the lines that point to the centre):


    And this is what it actually looks like:


    Code (CSharp):
    1. public class ShapeMaker : MonoBehaviour {
    2.      public Vector3[] vertices = new Vector3[8];
    3.      public Vector2[] shapeUV = new Vector2[8];
    4.      public List<float> angles = new List<float>();
    5.      public List<float> magnitudes = new List<float>();
    6.      int[] tris = new int[9];
    7.      void Start()
    8.      {
    9.          generateShape();
    10.          Mesh mesh = new Mesh();
    11.          GetComponent<MeshFilter>().mesh = mesh;
    12.          mesh.vertices = vertices;
    13.          mesh.uv = shapeUV;
    14.          mesh.triangles = tris;
    15.      }
    16.      public void generateShape()
    17.      {
    18.          //Generate Angles
    19.          for (int j = 0; j < vertices.Length; j++)
    20.          {
    21.              float direction = Random.Range(-2f, 2f);
    22.              angles.Add(direction);
    23.          }
    24.          angles.Sort();
    25.        
    26.          //Generate Magnitudes
    27.          for (int j = 0; j < vertices.Length; j++)
    28.          {
    29.              float magnitude = Random.Range(1f, 3f);
    30.              magnitudes.Add(magnitude);
    31.          }
    32.        
    33.          //Combining into Vectors
    34.          int i = 0;
    35.          foreach(float direction in angles)
    36.          {
    37.              float magnitude = magnitudes[i];
    38.              float cx = magnitude * Mathf.Cos(direction);
    39.              float cy = magnitude * Mathf.Sin(direction);
    40.              vertices[i] = new Vector3(cx, cy, 0);
    41.              shapeUV[i] = new Vector2(cx, cy);
    42.              tris[i] = i;
    43.              i++;
    44.          }
    45.        
    46.        
    47.          GetComponent<PolygonCollider2D>().pathCount = 1;
    48.          GetComponent<PolygonCollider2D>().SetPath(0, shapeUV);
    49.      }
    50. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    The problem is you are adding a vert, then adding a triangle entry, the old "triangle fan" or "triangle strip" method.

    Unity meshes only work on triangles. That means you add three verts, then add a single triangle comprising of their three indices, etc., etc. The tris[] array is always a multiple of three.

    Given what I think you're trying to do, you want to add the first center vert, then add your periphery verts, but every time you go to add a triangle, it must consist of the central vert, and two peripheral verts going around, and don't forget to wrap back up and close that final fan slot.

    For instance, to add a single quad, it is two triangles on four verts:

    verts: 0, 1, 2, 3 (going clockwise around from viewpoint)

    triangles: 0,1,2 and 0, 2, 3 (for example), a total of six integer indices.

    Winding is also important. Unity uses a left-handed winding, so if you are regarding a triangle, the verts have to be added in clockwise order, otherwise the triangle will face away and be culled.

    If you want double-sided triangles, simply add them twice, once winding each way, such as (0,1,2) and (0,2,1), etc.