Создание 2D круговой сетки в Unity - PullRequest
0 голосов
/ 30 мая 2018

В настоящее время у меня есть скрипт «CreateMesh», который можно поместить в качестве компонента объекта с помощью Mesh Renderer и Mesh Filter, и 2D-сетка создается с помощью многоугольного коллайдера в размерах сетки, заданной как «»Переменная MeshType "установлена ​​в" tri "или" box "(для треугольника и прямоугольной сетки соответственно.) Я также хочу добавить возможность создания круговой сетки, однако из некоторых исследований я понял, что это не так простокак я сначала подумал.Однако я еще не нашел ничего, что могло бы помочь.

Вот код, который у меня есть для ячеек и треугольных ячеек:

public float width = 5f;
public float height = 5f;

public string meshType;

public PolygonCollider2D polyCollider;

void Start()
{
    polyCollider = GetComponent<PolygonCollider2D>();
}

// Update is called once per frame
void Update () {
    if (meshType == "tri")
    {
        TriangleMesh(width, height);
    }
    if (meshType == "box")
    {
        BoxMesh(width, height);
    }

}

void TriangleMesh(float width, float height)
{
    MeshFilter mf = GetComponent<MeshFilter>();
    Mesh mesh = new Mesh();
    mf.mesh = mesh;

    //Verticies
    Vector3[] verticies = new Vector3[3]
    {
        new Vector3(0,0,0), new Vector3(width, 0, 0), new Vector3(0, height, 0)
    };

    //Triangles
    int[] tri = new int[3];

    tri[0] = 0;
    tri[1] = 2;
    tri[2] = 1;

    //normals
    Vector3[] normals = new Vector3[3];

    normals[0] = -Vector3.forward;
    normals[1] = -Vector3.forward;
    normals[2] = -Vector3.forward;

    //UVs
    Vector2[] uv = new Vector2[3];

    uv[0] = new Vector2(0, 0);
    uv[0] = new Vector2(1, 0);
    uv[0] = new Vector2(0, 1);

    //initialise
    mesh.vertices = verticies;
    mesh.triangles = tri;
    mesh.normals = normals;
    mesh.uv = uv;

    //setting up collider
    polyCollider.pathCount = 1;

    Vector2[] path = new Vector2[3]
    {
        new Vector2(0,0), new Vector2(0, height), new Vector2(width, 0)
    };

    polyCollider.SetPath(0, path);

}

void BoxMesh(float width, float height)
{
    MeshFilter mf = GetComponent<MeshFilter>();
    Mesh mesh = new Mesh();
    mf.mesh = mesh;

    //Verticies
    Vector3[] verticies = new Vector3[4]
    {
        new Vector3(0,0,0), new Vector3(0, height, 0), new Vector3(width, height, 0), new Vector3(width, 0, 0)
    };

    //Triangles
    int[] tri = new int[6];

    tri[0] = 0;
    tri[1] = 1;
    tri[2] = 3;

    tri[3] = 1;
    tri[4] = 2;
    tri[5] = 3;

    //normals
    Vector3[] normals = new Vector3[4];

    normals[0] = -Vector3.forward;
    normals[1] = -Vector3.forward;
    normals[2] = -Vector3.forward;
    normals[3] = -Vector3.forward;

    //UVs
    Vector2[] uv = new Vector2[4];

    uv[0] = new Vector2(0, 0);
    uv[1] = new Vector2(0, 1);
    uv[2] = new Vector2(1, 1);
    uv[3] = new Vector2(1, 0);

    //initialise
    mesh.vertices = verticies;
    mesh.triangles = tri;
    mesh.normals = normals;
    mesh.uv = uv;

    //setting up collider
    polyCollider.pathCount = 1;

    Vector2[] path = new Vector2[4]
    {
        new Vector2(0,0), new Vector2(0, height), new Vector2(width, height), new Vector2(width, 0)
    };

    polyCollider.SetPath(0, path);

}

Итак, по сути, я хочу функцию, которую я мог бы вызвать в методе обновления, который бы просто создавал круговую сетку.Например:

void Update () {
   if (meshType == "tri")
   {
       TriangleMesh(width, height);
   }
   if (meshType == "box")
   {
       BoxMesh(width, height);
   }
   if (meshType == "circle")
   {
       CircleMesh(radius);
   }
}

1 Ответ

0 голосов
/ 31 мая 2018

Решение, которое мне удалось найти, заключается в создании правильного многоугольника из n сторон с большим значением n.У меня есть функция с именем PolyMesh, которая создает регулярную полигональную сетку с n сторонами и данным радиусом.

Генерация вершин

Для каждой вершины правильного многоугольника с n сторонами координаты относительно центра многоугольника задаются x = r*i*sin(θ) и y = r*i*cos(θ), поэтому x = r*i*sin(2π/2) и y = r*i*cos(2π/2).Где я перебираю от 0 до n-1.Поэтому у нас может быть список, которому назначены вершины, а затем преобразуется в массив:

    //verticies
    List<Vector3> verticiesList = new List<Vector3> { };
    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();

Генерация треугольников

Заданный правильный многоугольник из n сторон может быть разбит на n-2 треугольников из одной и той же точки.Таким образом, мы можем сгенерировать каждый треугольник следующим образом:

    //triangles
    List<int> trianglesList = new List<int> { };
    for(int i = 0; i < (n-2); i++)
    {
        trianglesList.Add(0);
        trianglesList.Add(i+1);
        trianglesList.Add(i+2);
    }
    int[] triangles = trianglesList.ToArray();

Генерация нормалей

Так как это 2d-объект, мы можем иметь каждый нормаль как -Vector3.forward, вот так:

    //normals
    List<Vector3> normalsList = new List<Vector3> { };
    for (int i = 0; i < verticies.Length; i++)
    {
        normalsList.Add(-Vector3.forward);
    }
    Vector3[] normals = normalsList.ToArray();

Генерация коллайдера

Мы могли бы просто использовать кольцевой коллайдер с таким же радиусом, но для того, чтобы эта функция работала для многоугольника меньшего размеразначение n мы должны использовать PolygonCollider2D.Поскольку вершины уже упорядочены в массиве вершин, мы можем просто использовать их как пути для нашего PolygonCollider2D.

    //polyCollider
    polyCollider.pathCount = 1;

    List<Vector2> pathList = new List<Vector2> { };
    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);

Полный код должен выглядеть следующим образом:

public PolygonCollider2D polyCollider;

void Start()
{
    polyCollider = GetComponent<PolygonCollider2D>();
}

void PolyMesh(float radius, int n)
{
    MeshFilter mf = GetComponent<MeshFilter>();
    Mesh mesh = new Mesh();
    mf.mesh = mesh;

    //verticies
    List<Vector3> verticiesList = new List<Vector3> { };
    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<int> trianglesList = new List<int> { };
    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<Vector3> normalsList = new List<Vector3> { };
    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<Vector2> pathList = new List<Vector2> { };
    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);
}

Введение в сетки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...