Unityでスクリプトからメッシュを生成する方法をわかりやすく?解説

今回はUnityでスクリプトからメッシュを生成してみようと思います。

LineRendererを使用すれば頂点を繋いだメッシュの生成が出来、

UnityのLineRendererを使うと指定した点を繋いだメッシュを作成する事が出来ます。LineRendererの設定項目を細かく見ていき簡単なサンプルを作成してみます。

TrailRendererを使用すればゲームオブジェクトの軌跡をメッシュを作成し表示する事が出来ます。

UnityのTrailRendererを使ってゲームオブジェクトの軌跡を表示してみます。カメラから弾を飛ばし弾の軌跡を表示したり、キャラクターの歩いた後に軌跡を表示しています。

ただ元々ある設定値を変更してメッシュを自動生成する為、自分で思い描いたようなメッシュを生成したい場合は自由度が低いです。

そこで今回はスクリプトから自分で頂点を設定し、そこからメッシュを生成してみようと思います。

スクリプトからメッシュを生成する方法はYouTubeにある動画でわかりやすく解説している方がいましたので、そちらを順に追っていくとこの記事よりもわかりやすいかも!?

スポンサーリンク

メッシュを生成する前に知っておくべき情報

Unityでメッシュを生成する為には頂点、UVMap、三角形の情報が必要になります。

頂点

頂点はメッシュを構成する点の情報です。

3Dの点なのでVector3の配列やListとしてデータを作り、それをMeshクラスのverticesに設定します。

Unityでメッシュを作る時は三角形で構成しなければいけない為、四角形の面を作成する時は三角形を2つ使って四角形を構成します。

メッシュの頂点

↑のような頂点座標を配列等に設定していきます。

UVMap

UVMapはメッシュに貼り付けるテクスチャの座標値を設定します。

UVMapは頂点毎にVector2の値を設定し、Meshクラスのuvに設定します。

例えば↓のようなテクスチャ画像を用意した場合は、

UVMap概要

テクスチャの横座標がU、縦座標がVとなり0から1の数値を取ります。

U、Vというのは3DCGの座標軸でX、Y、Zを使っているので他のU、Vを使っているみたいです。

メッシュを作成した時にテクスチャを貼り付けたいと思った時、↑の画像の縦横半分だけを貼り付けたい時は、Uを0から0.5、Vを0から0.5の値を設定しメッシュを作成すればいいことになります。

先ほどの頂点に先ほどのテクスチャを割り当てるとすると、

頂点とUVの割り当て

↑のようになり、頂点(0, 0, 0)にはUV(0, 0)、頂点(1, 0, 0)にはUV(1, 0)、頂点(0, 1, 0)にはUV(0, 1)、頂点(1, 1, 0)にはUV(1, 1)を割り当てればテクスチャ全体が四角形の面に表示される事になります。

説明だけでは解り辛いですが、後でサンプルを作成するのでそこでわかると思います。

三角形

Unityでは三角形を繋げてメッシュを作成する必要がある為、その三角形を構成する3つの頂点を先ほどの頂点配列の番号を指定して設定する必要があります。

頂点配列が

(0, 0, 0)、(0, 1, 0)、(1, 0, 0)という順番で配列に格納されていた場合、この順番で三角形を構成しようとしたら、

0、1、2

という頂点配列の番号を三角形に指定する必要があります。

三角形の情報もVector3の配列やListとして登録する必要がある為、それぞれの三角形を構成する3つの頂点を設定していきますが、パッと見ただの配列情報になります。

現時点では何を言ってるかわからないかもしれませんが、サンプルを作成すると少しわかると思います。

四角形を作る時は頂点を4つ作成すれば三角形を作れますが、三角形のそれぞれの面の光の当たり方を変更したい場合は頂点を6つ作ります。

メッシュの頂点を共有するかしないか

↑が頂点を共有して四角形を作る場合と頂点を共有しないで四角形を作る時のイメージです。

下の頂点を共有しない場合は頂点のVector3の値は同じですが、三角形を構成する時に別の頂点として設定します。

三角形を構成する頂点の順番について

三角形を構成する頂点の番号を配列に入れる場合に注意しなければいけないのは順番です。

配列に入れた順番で三角形を作っていきますが、その順番によってメッシュの向きが変わります。

頂点は時計回りに繋いだ面が表になります。

頂点の繋ぎ方でメッシュの裏表が変わる

例えば↑の頂点を使って三角形を作る場合

(0, 0, 0)→(0, 1, 0)→(1, 0, 0)の順番で三角形を作った面は手前側がメッシュの表面になり、向こう側がメッシュの裏になります。
(1, 0, 0)→(1, 1, 0)→(0, 1, 0)の順番で三角形を作った面は向こう側がメッシュの表面になり、手前側が裏になります。

スクリプトからメッシュを生成してみる

メッシュの作り方がわかったので、実際にスクリプトからメッシュを生成してみます。

4つの頂点で四角形の面を作成

まずは4つの頂点を作り四角形を作ってみます。

頂点配列verticesをVector3型、UV配列uvsをVector2型、三角形配列trianglesをint型の配列で宣言します。

Startメソッドで頂点、UV、三角形の値を設定します。

verticesの配列の順番とuvsの配列の順番が対応します。

三角形であるtrianglesではverticesの配列のデータ順で三角形を構成する頂点を指定しています。

0、1、2という順番で最初の三角形を構成するので、verticesの頂点(0, 0, 0)、(0, 1, 0)、(1, 1, 0)で作ります。
次の0、2、3ではverticesの頂点(0, 0, 0)、(1, 1, 0)、(1, 0, 0)で三角形を作ります。

三角形の項目で書いたように時計回りの面がメッシュの表面になります。

三角形は頂点が3つ必要なのでMeshに設定する時に3の倍数でない場合はエラーになります。

三角形を構成する頂点がわかりやすいように、1つの三角形の頂点毎に改行してわかりやすくしています。

メッシュを設定するにはMeshFilter、メッシュを表示するにはMeshRendererコンポーネントが必要な為、AddComponentを使ってスクリプトからコンポーネントを取り付けています。

Updateメソッドで自前のCreateMeshメソッドを引数を与えて呼び出し、メッシュの作成をします。

メッシュを一旦Clearメソッドでクリアにし、その後Meshクラスのvertices、uv、trianglesに作成した配列を設定しメッシュを作成します。

メッシュ作成後はBoundsの再計算とNormalMapの再計算をしています。

メッシュ生成後ノーマルマップ(法線(メッシュの表面の方向))の方向が別の方向になっていますので再計算をします。

ヒエラルキー上に空のゲームオブジェクトを作成しこのスクリプトを取り付け、Materialに何らかのマテリアルを作成し取り付けてます。

メッシュは空のゲームオブジェクトからの相対値の頂点位置に作成されるのでゲームオブジェクトを移動してみてください。

それでは実行してみます。

4つの頂点で作成したメッシュ

↑のようにUnityを実行するとメッシュが生成され指定したマテリアルのテクスチャがUVの情報によって貼り付けられています。

メッシュの表面をカメラの方向にしているので、回転させて裏側を見るとメッシュが表示されません。

メッシュの裏側が表示されないのはマテリアルに設定しているシェーダ―スクリプトで裏面を表示しないようにしている為表示されていません。

裏側も表示するシェーダ―を指定すれば裏側から見てもメッシュが表示されます。

テクスチャを4分割した左下だけを表示する

先ほどのスクリプトではテクスチャの前面を四角形に表示しましたが、UVに設定する値を変更し4分割の左下だけを表示するようにしてみます。

uvの設定部分だけを下のように変更してください。

UVの座標を変更したことで、左下の部分のテクスチャだけがメッシュに割り当てられます。

メッシュにテクスチャの左下だけを表示

↑のようにテクスチャの割り当てる部分を変更出来ます。

6つの頂点を使って四角形の面を作成

次は6つの頂点を使って四角形の面を作成してみます。

verticesには同じVector3の頂点を別に登録し、6つの頂点を使ってtrianglesに登録しています。

6つの頂点から作成した四角形のサンプル

6つの頂点で作成した面は光の当たりぐあい等が変わってきます。

UVは適当に設定しています。

頂点の共有ありなしで光の当たり具合の変化

次に頂点の共有で作ったメッシュと頂点を共有しないで作ったメッシュの光が当たった時の違いを見ていきます。

頂点、UV、三角形の設定値を変えるだけなので、そこの部分だけ記載します。

まずは頂点を共有する場合

頂点を共有しない場合

それぞれのスクリプトを別の空のゲームオブジェクトに設定し実行します。

Unity実行後にMeshRendererのCast ShadowsをOff、Receive Shadowsのチェックを外します。

左側が頂点を共有したメッシュ、右が共有しないメッシュです。

メッシュの共有ありなしでの光の当たり具合

Directional Lightの角度を変え光の当たり具合を確認します。

Directional LightはTransformの位置に関係なく角度だけが光の当たり具合に影響します。

共有した方はメッシュ全体が光の影響を受けている感じで、共有していない方は当たる角度によって暗いままになっています。

終わりに

スクリプトからメッシュを作成出来るようになると自動で地面を作成したり、ダンジョンを作成したりといった事まで出来ますね(^^)/

メッシュの構成を考えると結構頭が痛くなりそうですけどね・・・・(^_^;)

Cubeのような簡単なメッシュをスクリプトから作るのも大変そうです・・・・(-_-)

スクリプトからメッシュを作成する事が出来たので、次回以降にキャラクターが剣を振った時の剣の軌跡をスクリプトから作ってみたいと思います。

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます