トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

unity_script_create_polygonmesh

ポリゴンメッシュの作成

スクリプトでポリゴンメッシュを作成するには、Meshクラスを使用します。

まずemptyなカラのGameObjectを作成しておき、ここに「Mesh Filter」と「Mesh Renderer」をコンポーネントとして登録しておきます。

スクリプト「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としてのジオメトリと名前を渡します。

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


 動的にポリゴンメッシュを再構成する

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];
}

のように、いったん配列に入れてから使用するほうがはるかに速くなる。


最終更新時間:2020年05月09日 10時02分04秒