
マイケル
みなさんこんばんは!
マイケルです!!
マイケルです!!

エレキベア
クマ〜〜〜〜

マイケル
さて、今回は Unityでスクリプトから動的にメッシュを作成する方法
について紹介していきます!
について紹介していきます!

エレキベア
形を変えたりできるクマ??
動的に作成するとどんなメリットがあるクマ?
動的に作成するとどんなメリットがあるクマ?

マイケル
頂点単位で操作できるようになるから、
スクリプトからメッシュを自由に量産できるし、
ゲーム中に変形することもできる んだ!
スクリプトからメッシュを自由に量産できるし、
ゲーム中に変形することもできる んだ!

エレキベア
自由自在にメッシュを操作できるなんて夢が広がるクマね

マイケル
それとペイント処理なんかにも使えるし、
透明部分が多い画像等は、必要な部分だけメッシュ描画することで
パーフォーマンスもよくなるみたいだよ。
透明部分が多い画像等は、必要な部分だけメッシュ描画することで
パーフォーマンスもよくなるみたいだよ。

マイケル
今回は簡単な図形の描画とアレンジを加えながら
メッシュ操作に慣れていこう!
メッシュ操作に慣れていこう!

エレキベア
やったるクマ〜〜〜
三角形メッシュの描画
メッシュの描画

マイケル
まずは一番簡単な三角形メッシュの描画から!
以下のようなスクリプトを記述してCanvas内の適当なGameObjectにアタッチ しましょう!
以下のようなスクリプトを記述してCanvas内の適当なGameObjectにアタッチ しましょう!

マイケル
するとこのようにSceneViewに三角形が描画されることが確認できます!

マイケル
スクリプトでは Graphicクラスを継承して、OnPopulateMesh()関数をオーバーライドしています。
この関数の引数で渡される VertexHelperを操作することでメッシュを描画することができる というわけです!
この関数の引数で渡される VertexHelperを操作することでメッシュを描画することができる というわけです!

マイケル
処理内容は非常に単純で、
・VertexHelper.AddVert() で3つの頂点座標を定義して
・VertexHelper.vh.AddTriangle() で描画するインデックス座標を指定する
という手順だけで描画することができます。
・VertexHelper.AddVert() で3つの頂点座標を定義して
・VertexHelper.vh.AddTriangle() で描画するインデックス座標を指定する
という手順だけで描画することができます。

エレキベア
三角形だと分かりやすいクマね

マイケル
頂点座標やインデックス座標について知らない方は、
以前座標変換についての記事も書いているのでこちらもご覧ください・・・。
以前座標変換についての記事も書いているのでこちらもご覧ください・・・。

エレキベア
なつかしクマ〜〜〜

マイケル
またこの時、頂点ごとにカラーを設定することもできます。
下記はそれぞれ赤、青、緑を指定した例です。
下記はそれぞれ赤、青、緑を指定した例です。

エレキベア
これは綺麗クマね
頂点を動的に移動させる

マイケル
三角形は描画できましたが、このままではゲーム中に座標を変更しても反映されません。
反映させるタイミングはUpdate内で SetVerticesDirty()を呼び出すことで指定 することができます。
反映させるタイミングはUpdate内で SetVerticesDirty()を呼び出すことで指定 することができます。
↑一定間隔でダーティフラグを設定する

マイケル
Dirtyは汚い、古いという意味で、状態が古くなったことを伝える処理 になります。
これはダーティフラグというデザインパターンが使用されている例になりますね。
これはダーティフラグというデザインパターンが使用されている例になりますね。

エレキベア
ダーティフラグはちまちま見たことあるクマ〜〜

マイケル
それでは更新されていることが分かるよう、各頂点の座標をランダムに動かしてみましょう!
↑乱数でランダムにoffsetを設定する

マイケル
するとこのようにうにゃうにゃ動くことが確認できました!

エレキベア
なんかかわいいクマ〜〜

マイケル
同じ容量で、頂点カラーも動的に変更できます。
下記は動的にグラデーションさせてみた例です!
下記は動的にグラデーションさせてみた例です!

エレキベア
さらに美しいクマ〜〜〜
四角形メッシュの描画
メッシュの描画

マイケル
慣れてきたところで四角形も描画してみましょう!
4つ頂点を指定するのはもちろんですが、三角ポリゴン単位での描画になる ことには注意です!
4つ頂点を指定するのはもちろんですが、三角ポリゴン単位での描画になる ことには注意です!

エレキベア
これもC++で開発した時はやってたクマね〜〜

マイケル
この場合は、(0,1,2)、(3,2,1)という2つのインデックス座標を定義することになります。
これを記述したスクリプトを見てみましょう!
これを記述したスクリプトを見てみましょう!

マイケル
このスクリプトをアタッチすると、無事描画することが確認できました!

エレキベア
やったクマ〜〜〜〜〜
Spriteの設定

マイケル
それでは次はこの四角形メッシュにSpriteを表示させてみましょう!
頂点4つのままでもいいですが、UnityのTextコンポーネントやImageコンポーネントは6つの頂点で定義されているみたいなので、合わせて6つの頂点を定義してみましょう。
頂点4つのままでもいいですが、UnityのTextコンポーネントやImageコンポーネントは6つの頂点で定義されているみたいなので、合わせて6つの頂点を定義してみましょう。

エレキベア
なんでそれぞれ定義されてるクマ?

マイケル
これは恐らく同じ頂点座標でも法線、UV座標が異なることがあるからじゃないかな。
下記の記事であたった問題だね・・・。
下記の記事であたった問題だね・・・。

エレキベア
懐かしいクマ・・・・

マイケル
スクリプトは下記の通り!
spriteの設定は、mainTextureをオーバーライドして設定し、頂点情報にはuv座標も渡してあげましょう!
spriteの設定は、mainTextureをオーバーライドして設定し、頂点情報にはuv座標も渡してあげましょう!

マイケル
すると下記のようにSpriteが描画されます!

エレキベア
(カニクマ・・・・。)

マイケル
ちなみにメッシュは変形可能だから、下記のように分割して表示することもできるよ!

エレキベア
(カニが引き裂かれたクマ・・・。)
アンチエイリアス処理

マイケル
ここからはおまけの内容になりますが、
簡易的なアンチエイリアス処理をかけてみましょう!
簡易的なアンチエイリアス処理をかけてみましょう!

マイケル
描画されたメッシュを拡大すると、何もしないと下記のようにギザギザになっていることが分かります。

エレキベア
ピクセル感がすごいクマ

マイケル
これにアンチエイリアスをかけた場合は下記のようになります。
すこしぼやけた感じですね。
すこしぼやけた感じですね。

エレキベア
これはどうやるクマ??

マイケル
下記は三角形の例だけど、頂点の外側にもう一つ、
頂点カラーを透明に設定した頂点を定義する ことで実現できるよ!
頂点カラーを透明に設定した頂点を定義する ことで実現できるよ!

マイケル
この時アンチエイリアスのエリアは四角形になるため、三角形2つずつで辺を描くことには注意しよう!
下記のような処理をスクリプトに追加してあげると適用できます!
下記のような処理をスクリプトに追加してあげると適用できます!

マイケル
外側の頂点は、
中心座標から頂点座標の正規化ベクトル * アンチエイリアスをかける幅
で設定してみました!
ON、OFFすると下記のようにうまく適用できていることが分かります!
中心座標から頂点座標の正規化ベクトル * アンチエイリアスをかける幅
で設定してみました!
ON、OFFすると下記のようにうまく適用できていることが分かります!

エレキベア
複雑な図形だともう少し考える必要がありそうクマね

マイケル
もっといろいろ触っていきたいところだけど、
今日の授業はここまでだ!!
今日の授業はここまでだ!!

エレキベア
おつかれさまクマ〜〜〜
おわりに

マイケル
さあ、今日の成果はこれだーー!!!

エレキベア
(なんだこれクマ・・・)

マイケル
日曜日がこれを作るだけで終わってしまった・・・。
悲しいけど、今後きっと役に立つはず・・!!
悲しいけど、今後きっと役に立つはず・・!!

エレキベア
まあ汎用性はありそうクマね

マイケル
また今後、複雑なことにも挑戦していこう!
それでは今日はこの辺で!
アデューー!!
それでは今日はこの辺で!
アデューー!!

エレキベア
クマ〜〜〜〜
【Unity】uGUI上に動的なメッシュを描画する 〜完〜
[参考文献]
Unityスクリプトリファレンス
【超基本uGUI編】Unity 動的にメッシュを生成してゴニョゴニョする
【Unity】動的に枠を描く話 – KAYAC enfineers’ blog