これらの情報のご利用により、何らかの不都合や損害が発生したとしても、当社は何らの責任を負うものではありません。
自己責任でご使用ください。
2018/09/05
はじめまして。
BACKBONEの中川です。
UnityのスキンメッシュにClothコンポーネントを追加すると、 Clothシミュレーションを行うことができます。 シミュレーション中、メッシュは自動で変形するため、 一度シミュレーションで変形した形状をもう一度得ようとしても、 任意のタイミングで再現させることはできません。 今回は、シミュレーション結果をデータ形式で入出力することで、 同じ形状を再度利用する方法をご紹介します。
①シンプルなメッシュの頂点位置を取得します。
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
逆に、メッシュに対して頂点位置を入力したい場合も、
同じコンポーネントにアクセスすることで実現できます。
Cubeから先ほど追加したスクリプト”GetVtx”はデタッチして、
代わりに以下のスクリプト”SetVtx”をアタッチします。

簡単に内容をご説明します。
まず新しいVector3リスト変数”myVertices”を作成し、
このリストに頂点位置の情報を格納します(GetVertices関数)。
そして適宜任意の頂点位置を変更し、
最後にこのリストをメッシュの頂点位置リストとしてセットします(SetVertices関数)。
(結果)

このように1つの頂点位置が変更され、
Cubeの1点をへこませたような形にすることができました。
なお、へこんだCubeについて各面の明るさが
少し不自然な見え方をしていることにご注意ください。
頂点位置を強制的に変更するにあたり、
ライトの当たり具合に関わる法線情報もあわせて変更しなければ、
このように不自然なライトの受け方をしてしまいます。
先ほどのスクリプトのStart関数の最後に次の一行を追加すれば、
法線ベクトルが頂点位置にあわせて再計算され、自然な明るさになります。
![]()
(結果)

Clothシミュレーション中の頂点位置に関しては、
先ほどのようにMeshFilterコンポーネントからではなく、
Clothコンポーネントのvertices変数から取得します。
また頂点位置の取得に際し、Meshクラスに備わっているgetVertices()のような関数は、
Clothコンポーネントには実装されていません。
for文で順次取得しましょう。

Clothシミュレーションによってメッシュが望みの形状となったタイミングで、
この頂点位置のリストを出力したデータがあれば、それを先述の方法で入力することで、
以降シミュレーションを行わずとも同じ形状を得ることができます。
以上、メッシュの頂点位置を入出力する方法の紹介でした。
これらを応用して、メッシュの頂点位置を入力する際に、
(係数)×(元の頂点位置との差分)の値を足せば
ブレンドシェイプと同等の機能を持たせることができます。
たとえばClothシミュレーションでメッシュを伸縮させ、
2パターン(伸ばしたときと縮ませたとき)のメッシュの頂点位置を出力すれば、
そのデータを利用して、下図のようにただの平面モデルから、
そのメッシュを伸縮させるリグを組むまでをUnity上で完結させることができます。

ぜひ試してみてください!