初识Unity Mesh

☆樱花仙子☆ 提交于 2021-01-04 12:01:16

Mesh概念:Mesh是Unity中的一个组件,称为网格组件。通俗的讲,Mesh是指模型的网格,3D模型是由多边形拼接而成,而多边形实际上是由多个三角形拼接而成的。所以一个3D模型的表面其实是由多个彼此相连的三角面构成。三维空间中,构成这些三角形的点和边的集合就是Mesh。

Mesh组成

1、顶点坐标数组vertexes 

2、顶点在uv坐标系中的位置信息数组uvs

3、三角形顶点顺时针或者逆时针索引数组triangles

4、MeshFiler组件,用于增加mesh属性

5、MeshRender组件,增加材质并渲染出来。

6、可能还需要每个顶点的法线的数组normals

using UnityEngine;
using UnityEditor;
using System.Collections;

public class GenMesh
{
    [MenuItem("GameEditor/scene/Weather/GenMesh")]
    static public void GenMeshM()
    {
        Mesh m1 = CreateRect();
        AssetDatabase.CreateAsset(m1, "Assets/_Resource/model/prefab/weather/m1.asset");
    }

    public static Mesh CreateRect()
    {
        Mesh mesh = new Mesh();

        int particleNum = 10;
        //顶点坐标
        Vector3[] verts = new Vector3[4 * particleNum]; 
        //uv坐标
        Vector2[] uvs = new Vector2[4 * particleNum];
        //三角形索引
        int[] tris = new int[2 * 3 * particleNum];

        Vector3 position;
        for (int i = 0; i < particleNum; i++)
        {
            int i4 = i * 4;
            int i6 = i * 6;

            position.x = 5 * i;
            position.y = 5 * i;
            position.z = 0;

            //顶点坐标
            verts[i4 + 0] = position;
            verts[i4 + 1] = position + new Vector3(2, 0, 0);
            verts[i4 + 2] = position + new Vector3(2, 2, 0);
            verts[i4 + 3] = position + new Vector3(0, 2, 0);

            //四个顶点在UV坐标系中的位置
            uvs[i4 + 0] = new Vector2(0.0f, 0.0f);
            uvs[i4 + 1] = new Vector2(1.0f, 0.0f);
            uvs[i4 + 2] = new Vector2(1.0f, 1.0f);
            uvs[i4 + 3] = new Vector2(0.0f, 1.0f);

            //顺时针绘制三角形0 1 2 / 0 2 3
            tris[i6 + 0] = i4 + 0;
            tris[i6 + 1] = i4 + 1;
            tris[i6 + 2] = i4 + 2;
            tris[i6 + 3] = i4 + 0;
            tris[i6 + 4] = i4 + 2;
            tris[i6 + 5] = i4 + 3;
        }

        mesh.vertices = verts;
        mesh.triangles = tris;
        mesh.uv = uvs;
        mesh.RecalculateBounds();

        return mesh;
    }

    public static Mesh CreateCircle()
    {
        Mesh mesh = new Mesh();

        int particleNum = 10;
        Vector3[] verts = new Vector3[4 * particleNum];
        Vector2[] uvs = new Vector2[4 * particleNum];
        int[] tris = new int[2 * 3 * particleNum];

        Vector3 position;
        for (int i = 0; i < particleNum; i++)
        {
            int i4 = i * 4;
            int i6 = i * 6;

            position.x = 5 * i;
            position.y = 5 * i;
            position.z = 0;

            verts[i4 + 0] = position;
            verts[i4 + 1] = position + new Vector3(2, 0, 0);
            verts[i4 + 2] = position + new Vector3(2, 2, 0);
            verts[i4 + 3] = position + new Vector3(0, 2, 0);

            uvs[i4 + 0] = new Vector2(0.0f, 0.0f);
            uvs[i4 + 1] = new Vector2(1.0f, 0.0f);
            uvs[i4 + 2] = new Vector2(1.0f, 1.0f);
            uvs[i4 + 3] = new Vector2(0.0f, 1.0f);

            //顺时针绘制三角形0 1 2 / 0 2 3
            tris[i6 + 0] = i4 + 0;
            tris[i6 + 1] = i4 + 1;
            tris[i6 + 2] = i4 + 2;
            tris[i6 + 3] = i4 + 0;
            tris[i6 + 4] = i4 + 2;
            tris[i6 + 5] = i4 + 3;
        }

        mesh.vertices = verts;
        mesh.triangles = tris;
        mesh.uv = uvs;
        mesh.RecalculateBounds();

        return mesh;
    }
}
View Code

 

代码示例生成的mesh是这个样子,未添加MeshRender,即没有材质和渲染的情况:

 

 

添加MeshRender,即有材质和渲染的情况:

 

 

using UnityEngine;
using System.Collections;

/*仅仅创建Mesh
 *
 *
 */
public class CreatMesh : MonoBehaviour
{

    private GameObject mMesh;
    private Material mMaterial;

    /*  Mesh属性
     *      长宽
     *      段数
     *      高度
     *      高度差
     */
    private Vector2 size;//长度和宽度
    private float minHeight = -10;//最小高度
    private float maxHeight = 10;//最大高度
    private Vector2 segment;//长度的段数和宽度的段数
    private float unitH;//最小高度和最大高度只差,值为正

    /*  顶点属性
     *      顶点
     *      uv
     *      三角形 
     */
    private Vector3[] vertexes;//顶点数
    private Vector2 uvs;//uvs坐标
    private int[] triangles;//三角形索引

    void Start()
    {
        creatMesh(100, 100, 3, 3, -10, 10);
    }

    private void creatMesh(float width, float height, uint segmentX, uint segmentY, int min, int max)
    {
        size = new Vector2(width, height);
        maxHeight = max;
        minHeight = min;
        unitH = maxHeight - minHeight;
        segment = new Vector2(segmentX, segmentY);

        if (mMesh != null)
        {
            Destroy(mMesh);
        }
        mMesh = new GameObject();
        mMesh.name = "CreateMesh";

        computeVertexes();
        DrawMesh();
    }

    private void computeVertexes()
    {
        int sum = Mathf.FloorToInt((segment.x + 1) * (segment.y + 1));//顶点总数
        float w = size.x / segment.x;//每一段的长度
        float h = size.y / segment.y;

        GetTriangles();

        int index = 0;
        vertexes = new Vector3[sum];
        for (int i = 0; i < segment.y + 1; i++)
        {
            for (int j = 0; j < segment.x + 1; j++)
            {
                float tempHeight = 0;
                vertexes[index] = new Vector3(j * w, 0, i * h);
                index++;
            }
        }
    }

    private void DrawMesh()
    {
        Mesh mesh = mMesh.AddComponent<MeshFilter>().mesh;//网格
        mMesh.AddComponent<MeshRenderer>();//网格渲染器

        mMaterial = new Material(Shader.Find("Diffuse"));//材质

        mMesh.GetComponent<Renderer>().material = mMaterial;

        /*设置mesh*/
        mesh.Clear();//更新
        mesh.vertices = vertexes;
        //mesh.uv 
        mesh.triangles = triangles;

        mesh.RecalculateNormals();
        mesh.RecalculateBounds();

    }

    private int[] GetTriangles()
    {
        int sum = Mathf.FloorToInt(segment.x * segment.y * 6);//三角形顶点总数
        triangles = new int[sum];
        uint index = 0;
        for (int i = 0; i < segment.y; i++)
        {
            for (int j = 0; j < segment.x; j++)
            {
                int role = Mathf.FloorToInt(segment.x) + 1;
                int self = j + (i * role);
                int next = j + ((i + 1) * role);
                //顺时针
                triangles[index] = self;
                triangles[index + 1] = next + 1;
                triangles[index + 2] = self + 1;
                triangles[index + 3] = self;
                triangles[index + 4] = next;
                triangles[index + 5] = next + 1;
                index += 6;
            }
        }
        return triangles;
    }
}
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!