在Unity中创建2D圆形网格 [英] Creating a 2D Circular Mesh in Unity

查看:193
本文介绍了在Unity中创建2D圆形网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有一个"CreateMesh"脚本,可以将其作为带有Mesh Renderer和Mesh Filter的对象的一个​​组件放置,并使用多边形对撞机在网格尺寸上创建2D网格,并给出""MeshType"变量设置为"tri"或"box"(分别用于三角形和矩形网格.)我还想添加创建圆形网格的功能,但是根据一些研究,我意识到这并不是那么简单就像我第一次想到的那样但是,我还没有找到任何有帮助的方法.

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 dimensions of the mesh given a "MeshType" variable is set to either "tri" or "box" (for a triangle and rectangle mesh respectively.) I want to also add the ability to create a circular mesh however from some research I've realised this isn't as simple as I first thought. However I'm yet to find anything that's helping.

这是框和三角形网格的代码:

This is the code I have for the box and triangle meshes:

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);

}

所以从本质上讲,我想要一个可以在update方法中调用的函数,该函数将简单地创建一个圆形网格.例如:

So essentially I want a function that I could call in the update method that would simply create a circular mesh. E.g:

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

推荐答案

我设法找到的解决方案包括创建一个n边的正多边形,其n值较大.我有一个称为PolyMesh的函数,该函数创建一个具有n个边和给定半径的规则多边形网格.

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.

生成顶点

对于具有n边的规则多边形的每个顶点,相对于多边形中心的坐标由x = r*i*sin(θ)y = r*i*cos(θ)给出,因此,x = r*i*sin(2π/2)y = r*i*cos(2π/2)给出.我从0迭代到n-1.因此,我们可以得到一个分配了顶点的列表,然后将其转换为数组:

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<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个三角形.这样我们可以生成每个三角形,如下所示:

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<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这样将每个法线都设置为:

Since this is a 2d object we can have every normal as -Vector3.forward like so:

    //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的路径.

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<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);

完整的代码应如下所示:

The complete code should look like this:

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);
}

网格简介

这篇关于在Unity中创建2D圆形网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆