UnityにおけるMeshの話。動的にメッシュを作成するまで
はじめに
UnityのMeshクラスのvertices、uv、SetTrianglesについての説明で、どんな値を入れると動的にメッシュが作れるかの話になります。法線の設定は説明しません。
先にコードについて
こんな感じのコードでX,Y方向に長さ2の平面を作成し、マテリアルを一つ設定できます。これがメッシュを動的に作成する基本的な形になると思います。
void SetImage()
{
MeshFilter meshFilter;
MeshRenderer meshRenderer;
Mesh mesh;
GameObject meshObject;
Material[] materials;
meshFilter = meshObject.GetComponent<MeshFilter>();
meshRenderer = meshObject.GetComponent<MeshRenderer>();
mesh = new Mesh();
if (meshFilter == null || meshRenderer == null)
{
Debug.LogErrorFormat("meshFilter: {0}, meshRenderer:{1}", meshFilter, meshRenderer);
}
Vector3[] Points = new Vector3[]
{
new Vector3(-1, -1, 0),
new Vector3(-1, 1, 0),
new Vector3(1, 1, 0),
new Vector3(1, -1, 0),
};
mesh.vertices = Points;
mesh.subMeshCount = 1;
mesh.SetTriangles(new int[]{0, 1, 2, 3, 0, 2}, 0);
mesh.uv = new Vector2[]
{
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(1, 1),
new Vector2(1, 0),
};
meshRenderer.sharedMaterials = materials;
meshFilter.sharedMesh = mesh;
}
Unityがどのようにオブジェクトを表示しているか
オブジェクトは三角形の平面の集まりで表されます。ここではこの三角形のことをポリゴンと呼ぶことにします。オブジェクトに柄を付ける、つまりこのポリゴンに柄を付けるとなると、ポリゴンの平面に画像を切り貼りするように設定する必要があります。
動的なメッシュの生成には「このポリゴンの頂点はどこか、どのポリゴンにどの画像のどこからどこまでを張り付けるか」などの情報を与える必要があります。
今回、Meshには全ての頂点位置を入れ、どの頂点が画像のどの部分と一致するように画像を張るか、どの頂点の組み合わせで平面とするかの情報を入れていきます。
Mesh.verticesについて
この変数には頂点情報を入れます。型はVector3[]です。
概要には
Returns a copy of the vertex positions or assigns a new vertex positions array.
(頂点位置のコピーを返すか、新しい頂点位置の配列を代入します)
と書かれています。そのため頂点情報を取得し、その中身を書き換えただけではコピーの書き換えになるため実際の頂点情報は変化しませんので注意してください。(これ以外にもいくつかコピーを返すものがあるので注意してください)
Mesh.SetTrianglesについて
この関数はどの頂点を結ぶような平面を作成するかを設定します。
3つで一つの平面になりますがまとめて指定します。
第2変数には何番目のマテリアルを使用するかを入れます。
ここで頂点を指定する順番によって描画される向きが変わります。
描画される向きが変わるとどうなるかについてですが、Unityのデフォルトの設定ではポリゴンはある片方から見た場合のみ描画され、逆側からみると描画されないようになっています。
基本的に時計周りになるように頂点を指定してあげてください。そうすると時計回りに選んだ視点からは見えるようになります。
Mesh.uvについて
ここにはマテリアルの画像のどの部分が頂点に対応するかを入力することになります。0~ 1までの値で指定することができます(0が左端、1が右端みたいな)。1を超えたとしても1.1が0.1に変換されたりします。
ポリゴンの頂点にのみ画像の情報を与えたことになりますが、残りの平面については頂点のuvの値をもとに補完したuvの値を使って画像の情報を抜き取ります。
例えば座標(0, 0 ,0)にuv = (0, 0)を設定し、座標(1, 0 ,0)にuv = (1, 1)を設定したとすると、(0.5, 0 ,0)にはuv = (0.5, 0.5)が補完されることになります。
これで簡単ではありますが、動的にメッシュの生成ができたと思います。
終わりに
本来であれば法線などを指定する必要がありますが今回はやってないです。興味がある方は調べてみてください。