首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Unity3D 程序化網格生成:定義 vertices、normals、UV 的正確姿勢

     編輯:程式設計疑難解答

核心概念

在 Unity 中,所有幾何體最終都由 Mesh 組成。要自定義網格數據,必須先實例化一個 Mesh 對象,再為其屬性賦值。

標準流程代碼

using UnityEngine;

public class ProceduralMesh : MonoBehaviour {
    void Start() {
        // 1. 創建 Mesh 實例
        Mesh mesh = new Mesh();
        mesh.name = "CustomMesh";

        // 2. 定義頂點位置(必須)
        Vector3[] vertices = new Vector3[] {
            new Vector3(0, 0, 0),
            new Vector3(1, 0, 0),
            new Vector3(0, 1, 0),
            new Vector3(1, 1, 0)
        };
        mesh.vertices = vertices;

        // 3. 定義三角形索引(必須,決定渲染順序)
        int[] triangles = new int[] { 0, 2, 1, 2, 3, 1 }; // 兩個三角形組成一個四邊形
        mesh.triangles = triangles;

        // 4. 定義法線(可選,影響光照)
        Vector3[] normals = new Vector3[vertices.Length];
        for (int i = 0; i < normals.Length; i++) normals[i] = Vector3.back; // 面向 -Z
        mesh.normals = normals;

        // 5. 定義 UV 坐標(可選,用於貼圖)
        Vector2[] uv = new Vector2[] {
            new Vector2(0, 0), new Vector2(1, 0),
            new Vector2(0, 1), new Vector2(1, 1)
        };
        mesh.uv = uv;

        // 6. 重新計算邊界、切線等(可選但推薦)
        mesh.RecalculateBounds();
        mesh.RecalculateTangents();

        // 7. 掛載到 MeshFilter
        GetComponent<MeshFilter>().mesh = mesh;
    }
}

常見坑點提醒

  • 順序很重要:先設 vertices,再設 triangles,否則索引越界。
  • UV 必須與頂點一一對應:長度必須等於 vertices.Length。
  • 法線缺失會導致模型全黑:若不手動指定,調用 mesh.RecalculateNormals() 自動生成。
  • 動態修改需標記:運行時修改 Mesh 後,建議調用 mesh.UploadMeshData(false) 提交到 GPU。

Mesh 結構示意 UV 映射示例 法線可視化

進階:使用 MeshData API(Unity 2020.1+)

對於大規模網格構建,推薦使用 Mesh.MeshDataArray 配合 Job System 與 Burst Compiler,實現多線程離線構建,大幅提升性能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved