Unity 備忘録テクニック(Scriptで3Dポリゴン表示する)




皆さんこんにちは、プロクラスの野間です。

今回は実際にプログラムで3Dの面(ポリゴン)を表示してみたいと思います。
早速やってみましょう。

■事前準備

・空のGameObject作成
・Scriptを作成
今回書くScript(Start関数)に書き込んでいきます

■頂点の用意

前回お話しした頂点と面情報のうち、まずは頂点から用意したいと思います。
頂点は(点)ですので1つの座標(x,y,z)だけで表現できます。
この頂点ですが、UnityではVector3で用意することになります。

頂点だけを複数用意しますので、配列を使うことになります。
この配列の順番(Index)が頂点の番号になり、後で使用します。

今回は次の3頂点を使います。
(0,0,0)
(0,1,0)
(1,1,0)
3Dですが、わかりやすくするためにZを全て「0」にしています。
これをUnityのプログラムで書くと次のようになります。
※Script の完成版は最後にまとめて書きます

Vector3[] vertex = new Vector3[] {
	new Vector3(0f, 0f, 0f),
	new Vector3(0f, 1f, 0f),
	new Vector3(1f, 1f, 0f)
};

プログラムでは書き方が色々ありますが、これは最初から座標が決まっていて、変数の宣言時に一緒に値を指定する場合の書き方になります。
(数字の後ろの「f」はおまじないだと思ってください。Vector3で直接数字を書く場合に数字の後ろにつけます。正確にはfloatを指定しています)

これで頂点が用意できました。

■面情報の用意(「面情報」は造語)

線の情報と書いた方がわかりやすいかもしれません。
先に用意した頂点をどのように線で結ぶかを指定する情報です。
線情報と書かなかったのは、この情報が面として扱われるためです。

さて、面の情報は直接座標を指定するのではなく、先の頂点座標の配列を指定することで実現します。
配列の指定は順番(Index)で指定することになりますので、整数の配列になります。
配列の番号は「0」から始まりますので、番号順に指定するのは 0, 1, 2 となります(指定した順番に線でつなぐ事になります)。

int[] face = new int[] {0, 1, 2};

これで「0 と 1」「1 と 2」をつなげるデータになります(最初の点と最後の点「2 と 0」は自動でつながります)。

これだけでは、ただ配列が2つあるだけです。
これを3Dの形状を管理するモデルデータを作って渡します。

Mesh mesh = new Mesh();

これに先の頂点や面情報を渡します。

mesh.vertices = vertex;
mesh.triangles = face;

これでモデルの準備は整いました。

■GameObject に各種 Component を用意

まずはやはりGameObjectを用意しましょう。
GameObject obj = new GameObject(“Object”);

これに Component を追加していきます。定番ですね。

必要な Component を確認するため、UnityEditorで何か3Dオブジェクトを作成して Inspector を見てみましょう。
(メニューの GameObject > 3D Object > Cube 等)

見ると次のようなものがあります
・Transform
・Cube(Mesh Filter)
・Mesh Renderer
・Box Collider
があります。

このうち、
・Cube(Mesh Filter)
は「Cube」は名前ですので、「Mesh Filter」を作ることになります。
そして、今回は当たりについては関係ありませんので、「Box Collider」は不要です。
したがって、
・Transform
・Mesh Filter
・Mesh Renderer
の3つの Component を追加することになります。

以前にやった通り、Component は new ではなく AddComponent で追加します。
MeshFilter は後で使いますので、追加したときに変数で保持しておきます。
ここまでをまとめると次のようになります。

Vector3[] vertex = new Vector3[] {
	new Vector3(0f, 0f, 0f),
	new Vector3(0f, 1f, 0f),
	new Vector3(1f, 1f, 0f)
};
int[] face = new int[] { 0, 1, 2 };
Mesh mesh = new Mesh();
mesh.vertices = vertex;
mesh.triangles = face;
GameObject obj = new GameObject("Object");
MeshFilter mesh_filter = obj.AddComponent<MeshFilter>();
obj.AddComponent<MeshRenderer>();

まだこれでは何も表示されませんよ?
「空」のモデルを作っただけです。先に用意した頂点データなどは作っただけでまだ使ってませんよね?

(vertex や face は宣言されているが、何処にも使われていない)

それでは、頂点データなどを指定しましょう。

■データの指定

3Dのデータは MeshFilter が持ちます。
実行した時に作成される GameObject 「Object」を選択して Inspector を確認してみましょう。
画像の赤丸部分になるのですが、現在は何も指定していませんので、None になっています。00_1

mesh_filter.mesh = mesh;

さぁ実行してみましょう。今度こそ三角形が表示されます。
01_1

なぜピンク色なのか!?については突っ込まないでください。
一言でいえば「まだ色を指定していないから」が原因で、Unity ではこれが初期値の色のようです。
では早速色の指定を・・・の前にまだまだ知っておいかないといけない事がありますので先にそちらをやります。

続きはまた次回。

今回のまとめプログラム

void Start () {
	Vector3[] vertex = new Vector3[] {
		new Vector3(0f, 0f, 0f),
		new Vector3(0f, 1f, 0f),
		new Vector3(1f, 1f, 0f)
	};
	int[] face = new int[] { 0, 1, 2 };
	Mesh mesh = new Mesh();
	mesh.vertices = vertex;
	mesh.triangles = face;

	GameObject obj = new GameObject("Object");
	MeshFilter mesh_filter = obj.AddComponent();
	//MeshRenderer mesh_renderer = obj.AddComponent();
	obj.AddComponent();
	mesh_filter.mesh = mesh;
}