Humanoidで使われるMeshに関する情報をまとめておきます。
Humanoidで使うということでboneへウェイトが塗られていたり, blendShapeが設定されていたりするものを想定しています。
(このようなMeshは毎フレーム、ボーンの変化に対する頂点位置の計算などをする必要があるのでMeshRendererではなく必ずSkinnedMeshRendererに設定されている必要があります)
Mesh
Mesh 公式リファレンス
SkinnedMeshRenderer.meshとSkinnedMeshRenderer.sharedMeshから取得できるが
前者はそのオブジェクト特有のメッシュで、変更しても他に影響がない
後者は変更によって同じメッシュを共有するオブジェクトに影響を与える
これを変更しただけではUnity再起動時に初期化されてしまうので
新しいMeshアセットとして書き出しておく必要があります。
vertices
verticesに頂点の位置(Vector3)が入っている
vertices.Lengthが頂点数
メッシュ内のローカル座標なのでワールド座標として扱いたい場合はTransform.TransformPoint(Vector3 localPosition)で変換する
normals(法線), uvs(uv情報), boneWeights(ウェイト情報)はindexでverticesと対応させている
normals.Length == uvs.Length == boneWeights.Length == vertices.Length
triangles
trianglesはverticesのindex情報を持っている
(3つの頂点で1つのポリゴンとしているため, triangles.Lengthは3の倍数)
([0, 1, 2]や[3, 4, 5]が一つのポリゴン)
Unityでは時計回りがポリゴンの表である
SubMesh
小さなメッシュの単位。1つのSubMeshには必ず1つのマテリアルが適応されている
Meshのマテリアル数==submeshの個数==Mesh.subMeshCount
Mesh.GetIndices(int submesh)で特定のSubMeshに所属する頂点のindex配列を取得できる
(頂点そのものの情報ではない。あくまでMesh.verticesと対応付けられたindex)
SkinnedMeshRenderer.sharedMaterialsで得られるMaterials配列のindexを引数に入れるとそのMaterialsに対応したSubMeshの情報を取得できる
頂点以外にもポリゴン(Mesh.GetTriangles(int submesh))なども取得できる
boneWeights
SkinnedMeshRendererしか持ちえない
boneIndex0~3はSkinnedMeshRenderer.bonesのindex情報を持っている
weight0~3はウェイト情報(0~1)
Mesh.boneWeightsで得た配列を変更した場合元データも変わってしまうため,
元は変更させたくない場合はMesh.GetBoneWeights(List boneWeights)を使う
blendShape
SkinnedMeshRendererしか持ちえない
SkinnedMeshRenderer.blendShapesで取得可能
存在するblendShapeの名前や変化量の変更はできないので
Mesh.ClearBlendShapesで一度削除して
新しい名前や変化量を設定してMesh.AddBlendShapeFrameで作成する必要がある
関連リンク・参考
http://edom18.hateblo.jp/entry/2017/06/09/080802
https://qiita.com/keito_takaishi/items/8e56d5117ee90502e864