Unityでメッシュをスクリプトでプロシージャルに生成する方法について何回かに分けて解説します。
- 第1回 Unityでプロシージャルモデリング (三角形・四角形・正多角形) - Qiita
- 第2回 Unityでプロシージャルモデリング (平面)
- 第3回 Unityでプロシージャルモデリング (直方体) - Qiita
- 第4回 Unityでプロシージャルモデリング (円柱) - Qiita
- 第5回 Unityでプロシージャルモデリング (球) - Qiita
- 第6回 Unityでプロシージャルモデリング (トーラス) - Qiita
今回は平面のメッシュを生成してみます。
Plane.cs
using UnityEngine;
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class Plane : MonoBehaviour
{
[SerializeField] private Vector2 size = new Vector2(4, 3);
[SerializeField] private Vector2Int segment = new Vector2Int(4, 3);
private void Awake()
{
Mesh mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
Vector3[] vertices = new Vector3[(segment.x + 1) * (segment.y + 1)];
int[] triangles = new int[segment.x * segment.y * 2 * 3];
Vector2 halfSize = size * 0.5f;
Vector2 sizeStep = size / segment;
int vi = 0;
for (int y = 0; y < segment.y + 1; y++)
{
for (int x = 0; x < segment.x + 1; x++)
{
vertices[vi++] = new Vector3(sizeStep.x * x - halfSize.x, sizeStep.y * y - halfSize.y, 0);
}
}
int ti = 0;
for (int y = 0; y < segment.y; y++)
{
for (int x = 0; x < segment.x; x++)
{
triangles[ti] = x + y * (segment.x + 1);
triangles[ti + 1] = triangles[ti + 5] = x + (y + 1) * (segment.x + 1);
triangles[ti + 2] = triangles[ti + 4] = (x + 1) + y * (segment.x + 1);
triangles[ti + 3] = (x + 1) + (y + 1) * (segment.x + 1);
ti += 6;
}
}
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
今回生成する平面は大きさと分割数をsize
とsegment
でインスペクターから任意に設定できるようにしています。
メッシュは以下のように構成されています(分割数はデフォルト値)。数字は頂点のインデックス、丸で囲まれた数字は三角形を定義する順番を表しています(途中で省略)。
図のように頂点は(segment.x + 1) * (segment.y + 1)
だけ必要になります。またメッシュを縦横で分割した四角形は2つの三角形で作れるので、三角形の数はsegment.x * segment.y * 2
になります。そのため、triangles
配列の大きさはsegment.x * segment.y * 2 * 3
になります。
ソースコードの以下の箇所で頂点を定義しています。XY平面上で作成するメッシュの中心が原点に一致するように頂点を配置しています。
Vector2 halfSize = size * 0.5f;
Vector2 sizeStep = size / segment;
int vi = 0;
for (int y = 0; y < segment.y + 1; y++)
{
for (int x = 0; x < segment.x + 1; x++)
{
vertices[vi++] = new Vector3(sizeStep.x * x - halfSize.x, sizeStep.y * y - halfSize.y, 0);
}
}
三角形の定義は以下の箇所で行っています。2重ループの中では2つの三角形で四角形を作成しています。2つの三角形から四角形を作成する方法については以前の記事を参照してください。
int ti = 0;
for (int y = 0; y < segment.y; y++)
{
for (int x = 0; x < segment.x; x++)
{
triangles[ti] = x + y * (segment.x + 1);
triangles[ti + 1] = triangles[ti + 5] = x + (y + 1) * (segment.x + 1);
triangles[ti + 2] = triangles[ti + 4] = (x + 1) + y * (segment.x + 1);
triangles[ti + 3] = (x + 1) + (y + 1) * (segment.x + 1);
ti += 6;
}
}