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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM