Unity Mesh(网格)
Mesh:
- vertices:
- normals:
- uv:
- tangents:
- boneWeights :
- colors/colors32:
//顶点位置数组
public Vector3[] vertices ;
//两种方法更改
//public void SetVertices (List<Vector3> inVertices);
mesh.SetVertices(vertices);
mesh.vertices = vertices;
//改变 vertices 后通常需要重新计算包围盒
mesh.RecalculateBounds();
//每一个顶点的法线方向
public Vector3[] normals ;
//uv列表
public Vector2[] uv ;
//网格的切线。
//切线最常用于凹凸贴图着色器中。切线是单位长度的矢量,它顺着网格 表面沿水平 (U) 纹理方向。Unity 中的切线表示为 Vector4, 其“x,y,z”分量定义矢量,而 w 用于在需要时翻转副法线。
//Unity 计算另一个表面矢量(副法线)的方法是获取法线与切线 之间的叉积,然后将结果乘以切线的 w。因此,w 应始终为 1 或 -1。
//如果计划在网格上使用凹凸贴图着色器,则应自己计算切线。 在分配 normals 或使用 RecalculateNormals 之后分配切线。
//注意:若要对 tangents 进行更改,从 Mesh 复制 切线十分重要。复制和更改 tangents 之后,normals 即可重新分配回 Mesh。
public Vector4[] tangents ;
//每个顶点的骨骼权重。
public BoneWeight[] boneWeights ;
//网格的顶点颜色。
//如果没有顶点颜色可用,则返回空数组。
public Color[] colors ;
//与 colors 相同,但是使用 Color32 结构的性能更好。
public Color32[] colors32 ;
- triangles:
//该数组是三角形的列表,包含顶点数组的索引,长度必须始终是 3 的倍数。
//使用此属性分配三角形数组时,subMeshCount 设置为 1。如果要具有多个子网格,请使用 SetTriangles。
public int[] triangles ;
public void SetTriangles (int[] triangles, int submesh, bool calculateBounds= true, int baseVertex= 0);
public void SetTriangles (int[] triangles, int submesh);
public void SetTriangles (List<int> triangles, int submesh, bool calculateBounds= true, int baseVertex= 0);
public void SetTriangles (List<int> triangles, int submesh);
public int[] GetTriangles (int submesh);
public int[] GetTriangles (int submesh, bool applyBaseVertex= true);
public void GetTriangles (List<int> triangles, int submesh, bool applyBaseVertex= true);
public void GetTriangles (List<int> triangles, int submesh);
//决定索引的布局为三角形、四边形等
public MeshTopology GetTopology (int submesh);
//* SetIndices 、GetIndices 、GetIndexStart 、GetIndexCount
//* 子网格的 GetIndices 方法得到索引列表,始终是在 mesh.vertices 中截取的范围,范围的起始索引为 GetIndexStart ,数量为 GetIndexCount。
//* 只能通过 SetIndices 来指定截取的范围。
//* 当为 MeshTopology(网格拓扑) 为 MeshTopology.Triangles(三角形) 时, GetIndices 与 GetTriangles 得到的结果是一致的
public void SetIndices (int[] indices, MeshTopology topology, int submesh, bool calculateBounds);
public void SetIndices (int[] indices, MeshTopology topology, int submesh);
public void SetIndices (int[] indices, MeshTopology topology, int submesh, bool calculateBounds= true, int baseVertex= 0);
public void GetIndices (List<int> indices, int submesh);
public int[] GetIndices (int submesh)
public uint GetIndexStart (int submesh);
public uint GetIndexCount (int submesh);
1.从头开始构建网格: 应始终按以下顺序进行: 分配 vertices -> 分配 triangles。
using UnityEngine;
public class Example : MonoBehaviour
{
Vector3[] newVertices;
Vector2[] newUV;
int[] newTriangles;
void Start()
{
Mesh mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
mesh.vertices = newVertices;
mesh.uv = newUV;
mesh.triangles = newTriangles;
}
}
2.每一帧都修改顶点属性:
a) 获取顶点
b) 修改它们
c) 将它们分配回网格。
using UnityEngine;
public class Example : MonoBehaviour
{
void Update()
{
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
for (var i = 0; i < vertices.Length; i++)
{
vertices[i] += normals[i] * Mathf.Sin(Time.time);
}
mesh.vertices = vertices;
}
}
3.连续更改网格三角形和顶点:
a) 调用 Clear 以开始刷新
b) 分配顶点和其他属性
c) 分配三角形索引。
在分配新顶点或三角形之前调用 Clear 十分重要。 Unity 始终检查提供的三角形索引是否未引用超出边界的顶点。 调用 Clear,分配顶点,然后分配三角形可确保不会有超出边界的数据。
using UnityEngine;
public class ExampleClass : MonoBehaviour
{
Vector3[] newVertices;
Vector2[] newUV;
int[] newTriangles;
void Start()
{
Mesh mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear();
// Do some calculations...
mesh.vertices = newVertices;
mesh.uv = newUV;
mesh.triangles = newTriangles;
}
}
创建四边形示例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestCreateMesh : MonoBehaviour{
public float width=2f;
public float height=1f;
private void Start(){
MeshFilter mf = GetComponent<MeshFilter>();
Mesh mesh = new Mesh();
mf.mesh = mesh;
Vector3[] vertices = new Vector3[4];
vertices[0] = new Vector3(0, 0, 0);
vertices[1] = new Vector3(width, 0, 0);
vertices[2] = new Vector3(0, height, 0);
vertices[3] = new Vector3(width, height, 0);
mesh.vertices = vertices;
int[] tri = new int[6];
tri[0] = 0;
tri[1] = 2;
tri[2] = 1;
tri[3] = 2;
tri[4] = 3;
tri[5] = 1;
mesh.triangles = tri;
Vector3[] normals = new Vector3[4];
normals[0] = Vector3.back;
normals[1] = Vector3.back;
normals[2] = Vector3.back;
normals[3] = Vector3.back;
mesh.normals = normals;
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(1, 0);
uv[2] = new Vector2(0, 1);
uv[3] = new Vector2(1, 1);
mesh.uv = uv;
}
}
不同材质多个子网格示例(在上面例子基础上,在左侧添加一个不同材质的矩形)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestCreateMesh : MonoBehaviour{
public float width=2f;
public float height=1f;
private void Start(){
MeshFilter mf = GetComponent<MeshFilter>();
Mesh mesh = new Mesh();
mf.mesh = mesh;
Vector3[] vertices = new Vector3[4];
vertices[0] = new Vector3(0, 0, 0);
vertices[1] = new Vector3(width, 0, 0);
vertices[2] = new Vector3(0, height, 0);
vertices[3] = new Vector3(width, height, 0);
mesh.vertices = vertices;
int[] tri = new int[6];
tri[0] = 0;
tri[1] = 2;
tri[2] = 1;
tri[3] = 2;
tri[4] = 3;
tri[5] = 1;
mesh.triangles = tri;
Vector3[] normals = new Vector3[4];
normals[0] = Vector3.back;
normals[1] = Vector3.back;
normals[2] = Vector3.back;
normals[3] = Vector3.back;
mesh.normals = normals;
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(1, 0);
uv[2] = new Vector2(0, 1);
uv[3] = new Vector2(1, 1);
mesh.uv = uv;
//********************************
//在左侧添加一个不同材质的矩形。注意: MeshRenderer.Materials 需要设置2个材质
Vector3[] vertices2=new Vector3[vertices.Length+4];
Array.Copy(vertices,vertices2,4);
vertices2[4] = new Vector3(0, 0, width);
vertices2[5] = new Vector3(0, 0, 0);
vertices2[6] = new Vector3(0, height, width);
vertices2[7] = new Vector3(0, height, 0);
mesh.vertices=vertices2;
int[] tri2 = new int[tri.Length+6];
Array.Copy(tri,tri2,6);
tri2[6] = 4;
tri2[7] = 6;
tri2[8] = 5;
tri2[9] = 6;
tri2[10] = 7;
tri2[11] = 5;
mesh.triangles = tri2;
Vector3[] normals2 = new Vector3[normals.Length+4];
Array.Copy(normals,normals2,4);
normals2[4] = Vector3.left;
normals2[5] = Vector3.left;
normals2[6] = Vector3.left;
normals2[7] = Vector3.left;
mesh.normals = normals2;
Vector2[] uv2 = new Vector2[uv.Length+4];
Array.Copy(uv,uv2,4);
uv2[4] = new Vector2(0, 0);
uv2[5] = new Vector2(1, 0);
uv2[6] = new Vector2(0, 1);
uv2[7] = new Vector2(1, 1);
mesh.uv = uv2;
mesh.subMeshCount=2;
//方法1:使用 SetIndices 方法 MeshTopology.Triangles 时,索引列表必须为3的倍数
mesh.SetIndices(new int[]{0,2,1, 2,3,1},MeshTopology.Triangles,0,true);
mesh.SetIndices(new int[]{4,6,5, 6,7,5},MeshTopology.Triangles,1,true);
//方法2:使用 SetTriangles
//mesh.SetTriangles(new int[]{0,2,1, 2,3,1},0,true);
//mesh.SetTriangles(new int[]{4,6,5, 6,7,5},1,true);
}
}
程序化网格几何体(Unity)
https://docs.unity.cn/cn/current/Manual/GeneratingMeshGeometryProcedurally.html
Mesh(Unity)
https://docs.unity.cn/cn/current/ScriptReference/Mesh.html
Unity中动态创建Mesh
https://www.cnblogs.com/answer-yj/p/11231247.html
使用Mesh创建一个Cube
https://www.cnblogs.com/kyokuhuang/p/4191169.html
水模型动态运动
https://blog.csdn.net/qwsx789/article/details/80351385
关于图形切割的问题
https://blog.csdn.net/thunderdreamer_or/article/details/104184589
unity实现任意多边形三角剖分
https://blog.csdn.net/huangzengman/article/details/77114082
图片转化为3d物体插件_UCLA Mesh Creator
https://blog.csdn.net/lizhenxiqnmlgb/article/details/82854800
将SpriteRenderer组件转换为Mesh
https://www.weixiuzhan.cn/news/show-17973.html