本記事内で公開している全ての情報について、その完全性、正確性、適用性、有用性等いかなる保証も行っておりません。
これらの情報のご利用により、何らかの不都合や損害が発生したとしても、当社は何らの責任を負うものではありません。
自己責任でご使用ください。
2018/09/05
はじめまして。
BACKBONEの中川です。
UnityのスキンメッシュにClothコンポーネントを追加すると、Clothシミュレーションを行うことができます。
一度Clothシミュレーションにより作成した形状を、改めてシミュレーションすることなく再現するために、
メッシュの各頂点位置を入出力する方法を紹介します。
1.頂点位置の出力
①シンプルなメッシュの頂点位置を取得します。
GameObject > 3D Object > Cube
プリミティブのCubeがシーン上に追加されます。
②次のようなC# スクリプトのコンポーネント”GetVtx”を作成し、Cubeにアタッチします。
(結果)
4頂点/面 x 6面 = 24頂点分の位置情報が、Vector3形式でログに出力されました。
Meshクラスのvertices変数には、indexに応じた頂点位置が格納されているようです。
(補足)
Meshクラスに関する詳細は、Unity公式のスクリプトリファレンスを参照ください。
https://docs.unity3d.com/ja/current/ScriptReference/MeshFilter-mesh.html
2.頂点位置の入力
逆に、メッシュに対して頂点位置を入力したい場合も、同じコンポーネントにアクセスすることで実現できます。
Cubeから先ほど追加したスクリプト”GetVtx”はデタッチして、代わりに以下のスクリプト”SetVtx”をアタッチします。
簡単に内容をご説明します。
まず新しいVector3リスト変数”myVertices”を作成し、このリストに頂点位置の情報を格納します(GetVertices関数)。
そして適宜任意の頂点位置を変更し、最後にこのリストをメッシュの頂点位置リストとしてセットします(SetVertices関数)。
(結果)
このように1つの頂点位置が変更され、Cubeの1点をへこませたような形にすることができました。
なお、へこんだCubeについて、各面の明るさが少し不自然な見え方をしていることにご注意ください。
頂点位置を強制的に変更するにあたり、ライトの当たり具合に関わる法線情報もあわせて変更しなければ、
このように不自然なライトの受け方をしてしまいます。
先ほどのスクリプトのStart関数の最後に次の一行を追加すれば、
法線ベクトルが頂点位置にあわせて再計算され、自然な明るさになります。
(結果)
3.Clothシミュレーションの頂点データの出力
Clothシミュレーション中の頂点位置に関しては、先ほどのようにMeshFilterコンポーネントからではなく、
Clothコンポーネントのvertices変数から取得します。
また頂点位置の取得に際し、Meshクラスに備わっているgetVertices()のような関数は、
Clothコンポーネントには実装されていません。
for文で順次取得しましょう。
Clothシミュレーションによってメッシュが望みの形状となったタイミングで、
この頂点位置のリストを出力したデータがあれば、それを先述の方法で入力することで、
以降シミュレーションを行わずとも同じ形状を得ることができます。
以上、メッシュの頂点位置を入出力する方法の紹介でした。
まとめ
これらを応用して、メッシュの頂点位置を入力する際に、(係数)×(元の頂点位置との差分)の
値を足せばブレンドシェイプと同等の機能を持たせることができます。
たとえばClothシミュレーションでメッシュを伸縮させ、2パターン(伸ばしたときと縮ませたとき)の
メッシュの頂点位置を出力すれば、そのデータを利用して、下図のようにただの平面モデルから、
そのメッシュを伸縮させるリグを組むまでをUnity上で完結させることができます。
ぜひ試してみてください!
参考:Unityスクリプトリファレンス
https://docs.unity3d.com/ja/current/ScriptReference/Mesh.html
https://docs.unity3d.com/jp/current/ScriptReference/Cloth.html