こんにちわ、Unityエンジニアのオオバです。

Unity 動的にメッシュを生成してゴニョゴニョする : 超基本編
3年前に執筆した↑記事の続きです。

Unity 動的に球のメッシュを描画をしてみる_19

先の記事シリーズでは、三角形を1個描画するところで終わっていますが、今回は↑のような球を動的に描画してみます。
パット見ハードルが一気に上がってそうですが、地道に1つずつ頂点の配置と順序を考えていけば大丈夫でした。

※注意 : 完全我流です。もっとシンプルな実装があるかもしれません。

Unity 動的に球のメッシュを描画をしてみる_26

本記事では説明しやすいように、分割数を少なくしています。横分割6、縦分割4です。
(上から見たら正六角形、横から見たら4つの面が縦に並んでいる状態です)

Unity 動的に球のメッシュを描画をしてみる_37

に分けて頂点座標配列とインデックス配列を作ります。

先の記事で説明していますが、Unityで動的にメッシュを作るにはVector3型の頂点座標配列int型配列の頂点インデックス配列が必要なので、これらを作成します。

頂点座標配列

今回これらのパラメータを変更できるようにしています。
天面、底面の頂点はそれぞれ、(0, r, 0), (0, -r, 0)となります。
※rは半径

問題は側面の頂点です。

Unity 動的に球のメッシュを描画をしてみる_59

球を横から見てみます。

θaは180度 / 縦分割数(ここでは4)で算出した角度(この場合45度)です。
緑のラインが頂点のy座標になるため、 y = consθa;になります。
薄いピンクは高さの頂点における円の半径になり、x座標、z座標を割り出し際に使用します。ここではtmpLenとします。
tmpLen = sinθaで割り出せます。

Unity 動的に球のメッシュを描画をしてみる_68

次に上から見てみます。
θbは360度 / 横分割数で算出した中心角です。
緑ラインがx座標、青ラインがz座標ということになります。

x = tmpLen * sinθbとなり、z = tmpLen * cosθbです。

この処理を分割数分for文で回すだけです。
縦の分割数に関しては、天面、底面は別の処理なので、その分イテレーションを減らす必要があります。

頂点座標配列を算出するコードはこちらです。
CreateSphereVertices_part.cs · GitHub

これで頂点座標配列は作成完了しました。
次に頂点インデックス配列の作成入ります。

頂点インデックス配列を作る

個人的には、頂点座標配列より、こちらの方が数倍複雑と感じました。
重要なのは頂点のIndex番号を頭の中で把握しておくことだと思います。

Unity 動的に球のメッシュを描画をしてみる_90

上から見た分割数を減らした球に、頂点番号を記載しました。

天面の頂点Index配列

Unity 動的に球のメッシュを描画をしてみる_96

緑の部分の天面の頂点Index配列を作っていきます。

天面は全て三角形なので想像しやすく、以下のような配列になるようにします。

0, 1, 2,  
0, 2, 3,  
0, 3, 4,  
~~~略~~~  
0, 6, 1  

コードはこんな感じです。

CreateSphereIndex_top_part.cs · GitHub

こんな感じで0始まりで三角形を作っていきます。注意点は1つだけ。最後の0, 6, 1の部分で、ループして1を使うところです。

側面の頂点Index配列

Unity 動的に球のメッシュを描画をしてみる_116

次に緑の部分の側面です。
上の画像は側面の一部ですが、他側面も実装する内容はほぼ同じです。

Unity 動的に球のメッシュを描画をしてみる_120

上の画像のように①〜⑤の順に頂点Index配列を作っていきます。

Unity 動的に球のメッシュを描画をしてみる_123

①から見ていきます。

1, 7, 8,  
1, 8, 2  

という順に頂点を結んで、三角形を2つ作ります。
四角形を一つ作り終えたら、開始のIndexをインクリメントして同じ処理を走らせます。簡単です。

この部分のコードはこんな感じになります。
CreateSphereIndex_side_part2.cs · GitHub

①の四角形の作りを上記のコードから確認していきます。

1, 7, 8,  
1, 8, 2  

繰り返しになりますが、上のインデックス配列で三角形2つを作成して①の四角形を作成しています。

Index番号 1, 7, 8の三角形
Index番号 1, 8, 2の三角形

ただ、上記のコードだと次の処理が抜けています。

Unity 動的に球のメッシュを描画をしてみる_157

それらを諸々考慮したコードは次になります。
CreateSphereIndex_side_part.cs · GitHub

底面の頂点Index配列

Unity 動的に球のメッシュを描画をしてみる_171

最後に底面です。
以下のような配列を作ります。

13, 14, 19,  
14, 15, 19,  
15, 16, 19,  
~~~~略~~~~~  
17, 18, 19  

天面とほぼ同じ(for文が逆になりますが)なので、説明は割愛しますが、コードはこうなります。
CreateSphereIndex_bottom_part.cs · GitHub

最後にこれらの配列をmeshにセットして描画します。この辺りは以前の記事で説明しているのでご参考ください。

テストコードも含めた全体コードはコチラ。
このコンポーネントをGameObjectにくっつければ球が生成されます。
Draw Sphere · GitHub

Unity 動的に球のメッシュを描画をしてみる_198

このようにメッシュの分割数も変更することもできます。

まとめ

三角形から飛躍して球のメッシュを動的に描画してみました。
地道に考えればできます。分割数を減らして考えるとより理解しやすい気がします。

この延長線でカプセル、トーラス辺りをやろうと思います。

ちなみに、UV座標を頂点に埋め込んでいないため、この球にテクスチャは貼れません。いつかやります。

以上

その他の動的にメッシュを生成するシリーズ

Unity動的にメッシュを生成するシリーズ

👉 オススメ記事

2021秋 Asset Refreshセール
100以上のアセットがなんと50%OFF!!オオバもいくつか買いました!
期間 : 10月2日午後3時59分まで

👩‍💻 検証環境