Excellent(PC版) Avatarの用意
やること
人の多いinstanceに顔を出すことも出てきたので、VRCのAvatar Performance Rank(PC版)のExcellentを満たすAvatarを用意する
工程
要件確認
壁になってくるのは次の要素だと思う。少なくとも自分の場合はそうだった。
- Polygons
- 32,000
- Skinned Meshes
- 1
- Material Slots
- 4
- Bones
- 75
- PhysBones Components
- 4
これらに注意しつつ対応していく
Polygons
まずは選択中のObjectの情報を表示する設定をONにして現状を把握する

できれば顔・髪・手あたりはローポリにしたくないので、服のポリ数をDecimate modifierで適当に減らしていく (Decimate modifierを使うとTopogolyはめちゃくちゃになりがちなので、もし服の着方などの調整がある場合には事前に行っておくこと。)

個人的な感覚だが、服をローポリにしていくだけでは32,000Poly以下に収めるのは難しそうだった。 そこで、服の内側に隠れている身体の部分は削除していくことにした。

これで32,000Poly以下になればOK
Skinned Meshes
結合元Objectをクリックしてから、結合先ObjectをCtrl+クリックする。その後にレイアウトウィンドウにカーソルを持ってきてからCtrl+Jで結合していく。

Material Slots
UVを編集するなどして、似た質感のObjectは単一Materialにまとめていく。4個のMaterialということは必然的にTextureの枚数も4枚になるはずなので、必要に応じてUVも直す。(UVに関しては今回は詳細を書かない) 今回は「髪」「服」「身体」「透過(表情用)」の4種類に分けた。

Bones
Humanoidのために必要そうなBone数だけで65ぐらいはありそうなので、上限の75までの10Bonesぐらいは自由につけられるようだ。 逆に言うと、Humanoidに必要でないBonesは10個までに抑える必要がある。 服とか髪についているBonesは極力削る。"_end"の名前がついたBonesも削除して良さそうだ。 心を鬼にしてBones数を削ること。

Bonesを削除したことによってWeightに影響がある可能性があるので、Pose modeとかで塗り忘れがないかを確認しておくと良いかも。

PhysBones Components
先程残したBonesに対して4個まではPhysBonesが設定できるので、Unity側で適当に設定していく。

確認
Excellent扱いになっていることが確認できればアップロードして終わり

感想等のメモ
Blender・Unityでのアバター管理メモ
やること
BlenderとUnityを使ってアバターの管理をしやすくする
何らかのツールを使うにしろ使わないにしろ、Unity上だけで衣服を追加していった結果、次の画像のような状態になった。

この状態になった結果、次のような問題に出くわした。
- 単純に無駄なボーン数が多くなり、パフォーマンスの低下を招きそうである
- 同名のボーンが多数存在するため、特定の衣服を削除しようとした際に、それに対応するボーンを見つけて削除することが困難である
- 着せたあとからBlenderで衣服の調整を行った場合、再びUnity側で着せ直す必要がある
これらの問題を解決するため、アバターとその衣服のfbxの管理をBlenderで行うことにする。
工程
BlenderでFBXを開き、エクスポート
Blenderで新規プロジェクトを作成し、アバターのFBXファイルをインポートする。その後名前をつけてエクスポートする。(今後も同名のファイル名でFBXファイルを上書き保存していくので、変更しなくて済むような名前をつけておく。)

エクスポートしたFBXをUnityで読み込む
先程作成したFBXを利用してUnity上でインスタンスを作成する。

Unity上のインスタンスにマテリアル・DB等を設定
先程のインスタンスにマテリアルやDynamicBone、VRCAvatarDescriptor等の設定をしていく。アバターのPrefabがあればそれを参考にして行う。

Blenderで衣服を着せて上書きする
あとは衣服を着せる度に同名のFBXファイルに上書きしていくだけで良い。冒頭に書いた問題点についてはそれぞれ次のように解決できたと思う。
- 単純に無駄なボーン数が多くなり、パフォーマンスの低下を招きそうである
Blenderで服を着せる際に重複したボーンを削除しておくことで、ボーン数を最低限に抑えられる。
- 同名のボーンが多数存在するため、特定の衣服を削除しようとした際に、それに対応するボーンを見つけて削除することが困難である
ボーンの管理はBlender側で行っているため、スキニングに関する情報をBlender側で確認して、不要になったと思われるボーンを削除すれば良い。
- 着せたあとからBlenderで衣服の調整を行った場合、再びUnity側で着せ直す必要がある
服を着せてから同名のFBXファイルとして上書き保存することで、Unity側でFBXをもとに生成したインスタンスが自動で更新される。そのため、一度着せたあとにUnity側でマテリアルを設定する必要こそあるが、その後に改めてBlenderで同じ服を微調整した場合にUnity側で何らかの作業を行う必要はない。
感想等のメモ
- 某氏から教えてもらった方法で、個人的にかなり気に入っている。(とはいえKiseteNe等のツールを使えばUnity上ですぐ着せられるようなので、そちらのほうが好みである人は居そうだなとも思う。また同時に、その場合はメッシュを微調整したくなったときに大変そうだなと思う。)
- Unity上でメッシュがどのボーンに追従するかの情報がどこに保存されているか詳しく知らないため、実はHipsはひとつを残してすべて消してもうまく動作するのでは?という疑問が残る。(試していない)
- Blender側から不完全なFBXで上書きしてしまった際、Unity側でのインスタンスの情報がめちゃくちゃになるので、UnityのプロジェクトをGit等で管理していないと危ないかも。
Avatar Dynamicsで遊んでみる①
やること
Avatar DynamicsのOpen Betaが始まったので触ってみる
今回はContactsを利用してParameterを変化させ、「右手を頭上の帽子に持ってきたときに、帽子を手に持つ・頭にかぶる状態を切り替えられる」状態にする。
今回作ったものの動作例がこれ。

工程
VRC Contact Senderの追加
今回は右手の人差し指が頭に触れたらイベントが発火するようにする。右手人差し指先端のボーンにVRCContactSenderを追加した。Collision TagsにはFingerIndexRを選択。

VRC Contact Receiverの追加
帽子のボーンにVRCContactReceiverを追加する…つもりだったが、移動させる(手に追従させる)ボーンにReceiverをつけると面倒なことが起きそうなので、帽子のボーンと同じ位置に新規でGameObjectを作成し、それにReceiverを追加した。
自分からだけ触れるようにするつもりなので、Allow Selfだけチェックをつけた。
先に設定したSenderと同じCollision Tagsを設定した。
今回は「帽子に手が触れた瞬間」にParameterが書き換わってほしいので、ReceiverTypeはOnEnterを選択。MinVelocityは初期値から変更していない。このParameterはBooleanでなくFloatしか許容してくれないようなので、Valueには1.0を入力(したら、1と表示された)。

ExParameterに同名のParameterを追加
VRC Avatar Descriptorに設定してあるExParameterを参照し、

先程Receiverで設定したParameterと同名のParameterを定義する。詳細は調べてないが、同名のParameterを参照している?(まさかそんなことある?)

ExParameters動作確認
この時点で、Avatar Debug Consoleを見ると「右手人差し指を頭上に持ってきた瞬間にだけisRightHandOnHeadが1.0になる」ことが確認できるはず。(下図の左下のParameter。図中では0になっている)

ここまででAvatar DynamicのContactの話は終わり。ここからは帽子を手に追従させるConstraintの話。
Constraint Sourcesの追加
帽子を固定したい階層にGameObjectを作成する。CapConstraintHeadとCapConstraintRightHandを作成した。このうち、頭用のCapConstraintHeadは先程VRCContactReceiverをつけたObjectも兼ねている。

Parent Constraintの追加
別のボーンに(回転も含めて)追従させたいので、帽子のボーンにParentConstraintを追加。Sourcesには先程作成したCapConstraintRightHandとCapConstraintHeadを追加。初期値で帽子は頭についていてほしいので、頭のほうを1にしておく。この時点でParent Contraint ComponentにあるZeroボタンを押しておくと良いらしい。(このボタンについては調べていない。)
持ち方を調整したかったらこの時点でSourcesの座標とか回転を調整しておくといいかも。

Animationの作成
Animationファイルを配置したいディレクトリで右クリ>Create>Animationで作成。
このAnimationファイルをHierarchy上のAvartarのInstanceにD&Dする(と、そのディレクトリにAnimationControllerが生成されるようだ。詳細は調べていない)。
それを開くとパラメータの存在しないアニメーション編集ウィンドウが表示されるので、その状態でHierarchy上のAvatarのInstanceをクリックすると、どういうわけか先程まで開いていたAnimationファイルとは関係なしに、そのInstanceに関連するAnimationの設定ができる状態になる。
この状態で赤い録画ボタンのようなものをクリック後、Constraint Sourcesの値を0とか1とかに適当に書き換えると、Animationウィンドウでそのパラメータが変更可能になる。
そうして、「帽子を手に持っているAnimationファイル」「帽子を頭にかぶっているAnimationファイル」を作成する。
(Animationウィンドウやファイルのことをあまり調べていないので、この謎の手順には納得していない。)

Animator Parametersの設定
Animatorタブのすぐ下にLayersタブとParametersタブがある。自分は最初これらのタブに気づかなかった。Parametersタブのほうで、先程ExParameterに追加したパラメータと同じ名前のパラメータをFloatで追加。自分は初期値を0.0にした(0と表示される。)

Animator Layersの設定
Layersのほうで新しいレイヤーを作成。レイヤー名の下にある灰色の線は飾りではなく、Weightを表すインジケータであることに気をつける。今回はアニメーションを合成したりはしないので、Weightは1で大丈夫のようだ。

「帽子を頭にかぶる」「帽子を手に持つ」という2種類のStateが必要なので、作成した。それぞれのStateに対応するAnimationを設定してある。ConditionsはどちらもisRightHandOnHead Greater 0。

このままだと、「手を頭に近づけた瞬間(OnEnter)だけhandのStateになり、次の瞬間にはheadに戻っている」状態になる。State Machineのことはさっぱりわからないので、どうやってバッファリングというか待機のようなことを行うのか不明だったのだが、Transition Duration (s)に適当な値を入れたところ、その時間中には改めてStateが遷移しないことがわかった。(この時間中に頭から手が離れれば、Stateはhandに遷移したままになる。)
あまり納得していないが、他の方法がわからない以上、一旦これを利用することにした。

以上で設定は終わり。
感想等のメモ
- HMD被ったりしながらデバッグするのが結構つらかったので、便利な方法があればぜひ知りたい。
- UnityもVRC SDKもよく知らない状態で挑んだので、問題が起きたときの原因の切り分けで苦労した。
- 本当は帽子を手に持った後にワールド固定をしたかったのだが、試しにPositionConstraintとRotationConstraintを入れてみたがうまくいかなかったので、理由の調査も含めて別の機会にまた試みることにした。