首先我们先在Unity3D中创建一个Cube,在Inspector可以看到其中含有MeshFilter、MeshRenderer组件。
由此可见如果你想要展示一个3D游戏物体,它必须拥有两个组件。
从官方手册中可以知道,在Mesh中存储着三维模型的数据:
vertices(顶点数据数组Vector3[])、
triangles(三角形顶点索引数组,int[])、
normals(法线向量数组,Vector3[])、
uv(纹理坐标数组,Vector2[])。
因此想要使用代码来创建Mesh需要至少四个步骤:
注意:Unity中的模型面数如果不进行特殊设置,默认是只渲染一面
比如正方体的俯视图,伸出你的左手,拇指环绕朝向的一面就是正面
首先创建空物体,添加必须的两个组件,然后添加代码脚本
上面贴图有四个顶点,正方形的面也是由四个顶点组成的,把图贴给面,四个顶点一一对应
结果:
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();
mesh = meshFilter.mesh;
meshRenderer = GetComponent();
// DrawTriangle();
// DrawSquare();
// DrawSquareWithTex();
DrawDoubleSquareWithTex();
}
///
/// 绘制一个三角面
///
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;
}
///
/// 绘制一个正方形(这是单面的)
///
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;
}
///
///绘制一个正方形并给生成的mesh赋予贴图
///
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;
}
///
/// 绘制双面的正方形
///
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;
}
}
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();
mesh = meshFilter.mesh;
meshRenderer = GetComponent();
DrawSquareWithTex();
}
///
///绘制一个正方形并给生成的mesh赋予贴图
///
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;
}
}
}