Unity 3D 创建Mesh(一)

本文详细介绍如何在Unity3D中创建自定义Mesh,包括计算顶点、三角形索引等核心步骤,并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Unity 3D 创建面片(Mesh)

Mesh是一种网格,可以产生像地形那样震撼的效果,那么怎样创建Mesh呢?那就要知道Mesh包含什么!
Mesh(网格):顶点、三角形、段数。

如图所示:该网格该如何表示呢?
顶点(vertexes)16=4*4
段数(segment)3*3
三角形(triangles)18
但是,三角形数目不是自己数,而是计算出来的。

二、创建Mesh属性

我们来创建一个长宽为100m*100m,高度为0m,段数为3*3的网格,如上图所示

    /*  Mesh属性 
         *      长宽 
         *      段数 
         *      高度 
         */  
        private Vector2 size;//长度和宽度  
        private float height= 0;//高度  
        private Vector2 segment;//长度的段数和宽度的段数  

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


    /*计算顶点,存入顶点数组*/  
    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 int[] GetTriangles()  
        {  
            int sum = Mathf.FloorToInt(segment.x * segment.y * 6);//三角形顶点总数:假设是1*1的网格,会有2个顶点复用,因此是6个顶点。假设是2*2的网格,则是4个1*1的网格,即4*6即2*2*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;  
        }  

到此:顶点、三角形计算完成!接下来是渲染。

三、渲染网格

在Unity 3D中,一个GameObject只有一个transform组件。我们在程序中,声明一个GameObject变量,通过添加MeshFilter来增加Mesh属性,通过MeshRenderer渲染出来,在MeshRenderer中,我们使用默认材质球。

    private GameObject mMesh;  
    private Material mMaterial;  

    mMesh = new GameObject();  
            mMesh.name = "CreateMesh";  

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

四、完整代码(有点不一样,扩充了点,拖在摄像机下面即可)

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

原文地址:http://blog.youkuaiyun.com/familycsd000/article/details/45366307

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值