トップ 一覧 検索 ヘルプ RSS ログイン

unity_script_create_polygonmeshの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!ポリゴンメッシュの作成
スクリプトでポリゴンメッシュを作成するには、Meshクラスを使用します。

まずemptyなカラのGameObjectを作成しておき、ここに「Mesh Filter」と「Mesh Renderer」をコンポーネントとして登録しておきます。
{{ref_image unity_create_mesh_01.png}}
スクリプト「CreatePolygonMesh.cs」というのを新規で作り、コンポーネントとして指定のGameObjectに追加しておきます。

GameObjectのコンポーネントとしては、
*Mesh Filter
*Mesh Renderer
*CreatePolygonMesh (script)
の3つが追加されている状態になります。

Mesh Filterは、ポリゴンメッシュのジオメトリを受け取るものです。中身についてはスクリプトで記載します。
Mesh Rendererは、レンダリングを一手に引き受けるものです。マテリアルもここで指定できます。

!!スクリプトの記述
 using UnityEngine;
 using System.Collections;
 
 public class CreatePolygonMesh : MonoBehaviour {
    private Mesh mesh;
    
    // Use this for initialization
    void Start () {
        mesh = new Mesh();      
        Vector3 [] newVertices = new Vector3[4];
        Vector2 [] newUV       = new Vector2[4];
        int[] newTriangles     = new int[2 * 3];
        
        // 頂点座標の指定.
        newVertices[0] = new Vector3(-2.0f, 0.0f,  2.0f);
        newVertices[1] = new Vector3(-2.0f, 0.0f, -2.0f);
        newVertices[2] = new Vector3( 2.0f, 0.0f, -2.0f);
        newVertices[3] = new Vector3( 2.0f, 0.0f,  2.0f);
        
        // UVの指定 (頂点数と同じ数を指定すること).
        newUV[0] = new Vector2(0.0f, 0.0f);
        newUV[1] = new Vector2(0.0f, 1.0f);
        newUV[2] = new Vector2(1.0f, 1.0f);
        newUV[3] = new Vector2(1.0f, 0.0f);
        
        // 三角形ごとの頂点インデックスを指定.
        newTriangles[0] = 2;
        newTriangles[1] = 1;
        newTriangles[2] = 0;
        newTriangles[3] = 0;
        newTriangles[4] = 3;
        newTriangles[5] = 2;
        
        mesh.vertices  = newVertices;
        mesh.uv        = newUV;
        mesh.triangles = newTriangles;
        
        mesh.RecalculateNormals();
        mesh.RecalculateTangents();
        mesh.RecalculateBounds();
        
        GetComponent<MeshFilter>().sharedMesh = mesh;
        GetComponent<MeshFilter>().sharedMesh.name = "myMesh";
    }
    
    // Update is called once per frame
    void Update () {
    
    }
 }

個々の頂点座標/UV/三角形のインデックスを配列に格納します。
UVについては頂点数と同じ数になるようにします。
三角形のインデックスは3頂点ごとに指定していきます。

「mesh = new Mesh();」でメッシュを生成し、
  mesh.vertices  = newVertices;
  mesh.uv        = newUV;
  mesh.triangles = newTriangles;
として、頂点/UV/三角形のインデックスの配列を渡します。

  mesh.RecalculateNormals();
  mesh.RecalculateTangents();
  mesh.RecalculateBounds();
として、法線とバウンディングボックスを再計算。
として、法線/法線マップ用のTangentSpaceとバウンディングボックスを再計算。
法線については、「mesh.normals」にVector3型の配列を直接渡してもよいです。
なお、「mesh.RecalculateTangents();」の指定がないと法線マップのマッピングは正しく行われません。

  GetComponent<MeshFilter>().sharedMesh = mesh;
  GetComponent<MeshFilter>().sharedMesh.name = "myMesh";
でGameObjectのMesh Filterとしてのジオメトリと名前を渡します。

これで実行すると、シーン上にスクリプトで作成されたポリゴンメッシュが表示されます。
{{ref_image unity_create_mesh_02.png}}

!!動的にポリゴンメッシュを再構成する
Update関数内で、
 Mesh mesh = GetComponent<MeshFilter>().mesh;
 Vector3[] vertices = mesh.vertices;
 for (int i = 0; i < vertices.Length; i++) {
   vertices[i].x += 0.01f;
 }
 mesh.vertices = vertices;
のように頂点座標を変更したり、「mesh.Clear()」としてジオメトリ情報をクリアして再度頂点/UV/三角形のインデックスを格納することにより、動的にポリゴンメッシュを作り直すことができます。

!!速度面での注意点

 for (int i = 0; i < mesh.vertices.Length; i++) {
    Vector3 v = mesh.vertices[i];
 }
のような実装は速度的にかなり遅い。

 Vector3[] vertices = mesh.vertices;
 int verCou = vertices.Length;
 for (int i = 0; i < verCou ; i++) {
    Vector3 v = vertices[i];
 }
のように、いったん配列に入れてから使用するほうがはるかに速くなる。

----
{{lastmodified}}