Unity中渲染出的3D物体组成内容
首先我们先在Unity3D中创建一个Cube,在Inspector可以看到其中含有MeshFilter、MeshRenderer组件。

unity3D Mesh圆管 unity绘制mesh_unity3D Mesh圆管

由此可见如果你想要展示一个3D游戏物体,它必须拥有两个组件。 

MeshFilter 这个组件记录了你想要展示的网格数据,相当于人的骨骼
MeshRenderer 使用这个组件告诉网格如何渲染,比如使用哪个材质球,是否接受阴影和其他设置,相当于人的皮肤,可以设置不同的贴图,化妆什么的。
Mesh中包含的内容
  从官方手册中可以知道,在Mesh中存储着三维模型的数据:

        vertices(顶点数据数组Vector3[])、

        triangles(三角形顶点索引数组,int[])、

        normals(法线向量数组,Vector3[])、

         uv(纹理坐标数组,Vector2[])。

因此想要使用代码来创建Mesh需要至少四个步骤:

1.设置顶点数组(想要创建的面一共有多少个顶点)
2.设置三角形信息(每三个顶点确定一个三角形,要顺时针的设置)
3.设置法线信息(可以通过mesh的方法直接计算)主要是跟光照有关的
4.设置UV信息(决定了图像信息如何在此Mesh上显示,其设置顺序和顶点数组的设置顺序相同)
注意:Unity中的模型面数如果不进行特殊设置,默认是只渲染一面

如何判断三角面的正反呢?
比如正方体的俯视图,伸出你的左手,拇指环绕朝向的一面就是正面

unity3D Mesh圆管 unity绘制mesh_unity_02

 

如何创建三角面
首先创建空物体,添加必须的两个组件,然后添加代码脚本

unity3D Mesh圆管 unity绘制mesh_贴图_03

 

unity3D Mesh圆管 unity绘制mesh_unity_04

 

如何创建正方形

unity3D Mesh圆管 unity绘制mesh_游戏引擎_05


给创建的正方形赋予贴图 

unity3D Mesh圆管 unity绘制mesh_unity3D Mesh圆管_06

上面贴图有四个顶点,正方形的面也是由四个顶点组成的,把图贴给面,四个顶点一一对应

unity3D Mesh圆管 unity绘制mesh_mesh_07

     

unity3D Mesh圆管 unity绘制mesh_贴图_08

 

unity3D Mesh圆管 unity绘制mesh_unity_09

unity3D Mesh圆管 unity绘制mesh_mesh_10

 

 创建双面的正方形

unity3D Mesh圆管 unity绘制mesh_贴图_11

 

unity3D Mesh圆管 unity绘制mesh_unity_12

 

unity3D Mesh圆管 unity绘制mesh_unity3D Mesh圆管_13

 

     结果:

     

unity3D Mesh圆管 unity绘制mesh_unity_14

  

unity3D Mesh圆管 unity绘制mesh_mesh_15

 

完整代码:

using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
  
 public class DrawMesh : MonoBehaviour
 {
     private MeshFilter meshFilter;
     private Mesh mesh;
     private MeshRenderer meshRenderer;
     //定义顶点数组
     private Vector3[] vertices = new Vector3[100];
     //存放三角面的顺序,所以一定是3的倍数
     private int[] triangels = new int[486];
  
     //给绘制的正方形附材质,材质贴图是一个四边形图片,
     private Vector2[] uvs;
     //正方形的材质球
     public Material mat;
     void Start()
     {
         meshFilter = GetComponent<MeshFilter>();
         mesh = meshFilter.mesh;
         meshRenderer = GetComponent<MeshRenderer>();
         //  DrawTriangle();
         // DrawSquare();
         // DrawSquareWithTex();
         DrawDoubleSquareWithTex();
     }
     /// <summary>
     /// 绘制一个三角面
     /// </summary>
     void DrawTriangle()
     {
         //定义上图的ABC三个顶点
         vertices = new Vector3[] { Vector3.zero, Vector3.forward, new Vector3(1, 0, 1) };
         //定义三个顶点的顺序,使其正面朝上 0表示第一个顶点,1表示第二个顶点
         triangels = new int[] { 0, 1, 2 };
         //在构造Mesh前最好clear下,如果Mesh再后来复用的话,一定要清空否则索引容易出现差错
         mesh.Clear();
         //给mesh赋值
         mesh.vertices = vertices;
         mesh.triangles = triangels;
     }
  
     /// <summary>
     /// 绘制一个正方形(这是单面的)
     /// </summary>
     void DrawSquare()
     {
         //定义上图的ABCD四个顶点
         vertices = new Vector3[] { Vector3.zero, Vector3.forward, new Vector3(1, 0, 1) ,Vector3.right};
         //0,1,2表示顺序ABC;2,3,0表示顺序CDA 两个三角面
         triangels = new int[] { 0, 1, 2,2,3,0 };
         //在构造Mesh前最好clear下,如果Mesh再后来复用的话,一定要清空否则索引容易出现差错
         mesh.Clear();
         //给mesh赋值
         mesh.vertices = vertices;
         mesh.triangles = triangels;
     }
     /// <summary>
     ///绘制一个正方形并给生成的mesh赋予贴图
     /// </summary>
     void DrawSquareWithTex()
     {
         //定义上图的ABCD四个顶点
         vertices = new Vector3[] { Vector3.zero, Vector3.forward, new Vector3(1, 0, 1), Vector3.right };
         //0,1,2表示顺序ABC;2,3,0表示顺序CDA 两个三角面
         triangels = new int[] { 0, 1, 2, 2, 3, 0 };
         //图片UV的四个点位置       
         uvs = new Vector2[] { Vector2.zero, new Vector2(0, 1), Vector2.one, new Vector2(1, 0) };
         //在构造Mesh前最好clear下,如果Mesh再后来复用的话,一定要清空否则索引容易出现差错
         mesh.Clear();
         //给mesh赋值
         mesh.vertices = vertices;
         mesh.triangles = triangels;
         //给正方形赋予材质球贴图
         mesh.uv = uvs;
         meshRenderer.material = mat;
  
     }
     /// <summary>
     /// 绘制双面的正方形
     /// </summary>
     void DrawDoubleSquareWithTex()
     {
         //定义正方形正反面的顶点
         vertices = new Vector3[] 
         { Vector3.zero, Vector3.forward, new Vector3(1, 0, 1), Vector3.right,//正面点
           Vector3.zero, Vector3.forward, new Vector3(1, 0, 1), Vector3.right//背面点
         };
         //0,1,2表示顺序ABC;2,3,0表示顺序CDA 两个三角面, 4,7,6   6,5,4 表示反的三角面
         triangels = new int[] { 0, 1, 2,   2, 3, 0 ,    4,7,6,  6,5,4       };
         //  uvs = new Vector2[] { Vector2.zero, new Vector2(0, 1), Vector2.one, new Vector2(1, 0) };
         //重新分配UV值,正面u是0到0.5的
         uvs = new Vector2[]
         { Vector2.zero, new Vector2(0, 1), new Vector2(0.5f, 1), new Vector2(0.5f, 0),//正面
          new Vector2(0.5f, 0), new Vector2(0.5f, 1),Vector2.one, new Vector2(1, 0)//反面
         };
         //在构造Mesh前最好clear下,如果Mesh再后来复用的话,一定要清空否则索引容易出现差错
         mesh.Clear();
         //给mesh赋值
         mesh.vertices = vertices;
         mesh.triangles = triangels;
         //给正方形赋予材质球贴图
         mesh.uv = uvs;
         meshRenderer.material = mat;
     }
 }


下面介绍下法线的使用

unity3D Mesh圆管 unity绘制mesh_贴图_16

unity3D Mesh圆管 unity绘制mesh_mesh_17

unity3D Mesh圆管 unity绘制mesh_unity_18

 

using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
  
 public class NormalTest : MonoBehaviour
 {
     private MeshFilter meshFilter;
     private Mesh mesh;
     private MeshRenderer meshRenderer;
     //定义顶点数组
     private Vector3[] vertices = new Vector3[100];
     //存放三角面的顺序,所以一定是3的倍数
     private int[] triangels = new int[486];
  
     //给绘制的正方形附材质,材质贴图是一个四边形图片,
     private Vector2[] uvs;
     //正方形的材质球
     public Material mat;
  
     public bool isChooseNormal;
     private Vector3[] normals = new Vector3[100];
     private Vector3[] normals1 = new Vector3[100];
     void Start()
     {
         meshFilter = GetComponent<MeshFilter>();
         mesh = meshFilter.mesh;
         meshRenderer = GetComponent<MeshRenderer>();
         DrawSquareWithTex();    
     }
     /// <summary>
     ///绘制一个正方形并给生成的mesh赋予贴图
     /// </summary>
     void DrawSquareWithTex()
     {
         //定义上图的ABCD四个顶点
         vertices = new Vector3[] { Vector3.zero, Vector3.forward, new Vector3(1, 0, 1), Vector3.right };
         //0,1,2表示顺序ABC;2,3,0表示顺序CDA 两个三角面
         triangels = new int[] { 0, 1, 2, 2, 3, 0 };
         //图片UV的四个点位置       
         uvs = new Vector2[] { Vector2.zero, new Vector2(0, 1), Vector2.one, new Vector2(1, 0) };
  
         normals = new Vector3[] { Vector3.up, Vector3.up, Vector3.up, Vector3.up };
         normals1 = new Vector3[] { Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero };
         //在构造Mesh前最好clear下,如果Mesh再后来复用的话,一定要清空否则索引容易出现差错
         mesh.Clear();
         //给mesh赋值
         mesh.vertices = vertices;
         mesh.triangles = triangels;
         //给正方形赋予材质球贴图
         mesh.uv = uvs;
         meshRenderer.material = mat;
     }
     private void Update()
     {
         if (isChooseNormal)
         {
             mesh.normals = normals;
         }
         else
         {
             mesh.normals = normals1;
         }
         
     }
 }