LQ El-Kyu

自分向け備忘録

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で結合していく。

Objectをひとつにしていく

Material Slots

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

4種類のMaterialに収めた

Bones

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

尻尾とサイドヘアのBonesは残した

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

背中あたりの服に塗り忘れがあった

PhysBones Components

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

サイドヘアと尻尾だけ揺れるようにした

確認

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

VRC SDK側の表示でExcellentになっていることを確認

感想等のメモ

  • 人数の多いイベント等で少しでも軽量なアバターを使えるので、少し気が楽になった。
    • Avatar Performance Rankは暫定的な基準であるが、今回はその基準を満たすこと自体を目的としてしまったため、本当に軽量かどうかは検証できておらず、確証はない。
  • 今回の記事では省略したが、特にUV展開まわりをやり直すのが大いに手間だった。他の人におすすめはできない。
  • Quest版のExcellent基準を満たせるAvatarを用意できればCustom fallbackに設定できるのだが、基準がPC版と比べて遥かに厳しいため、それは別の機会に試みることにする。

Blender・Unityでのアバター管理メモ

 

やること

BlenderとUnityを使ってアバターの管理をしやすくする

 

何らかのツールを使うにしろ使わないにしろ、Unity上だけで衣服を追加していった結果、次の画像のような状態になった。

f:id:ElmaKyune:20220331185256p:plain

Hipsいくつあるんだよ状態

この状態になった結果、次のような問題に出くわした。

  • 単純に無駄なボーン数が多くなり、パフォーマンスの低下を招きそうである
  • 同名のボーンが多数存在するため、特定の衣服を削除しようとした際に、それに対応するボーンを見つけて削除することが困難である
  • 着せたあとからBlenderで衣服の調整を行った場合、再びUnity側で着せ直す必要がある

これらの問題を解決するため、アバターとその衣服のfbxの管理をBlenderで行うことにする。

 

工程

BlenderでFBXを開き、エクスポート

Blenderで新規プロジェクトを作成し、アバターのFBXファイルをインポートする。その後名前をつけてエクスポートする。(今後も同名のファイル名でFBXファイルを上書き保存していくので、変更しなくて済むような名前をつけておく。)

f:id:ElmaKyune:20220331191007p:plain

BlenderでFBXをインポートした様子

エクスポートしたFBXをUnityで読み込む

先程作成したFBXを利用してUnity上でインスタンスを作成する。

f:id:ElmaKyune:20220331190638p:plain

FBXからインスタンスを作成

Unity上のインスタンスにマテリアル・DB等を設定

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

f:id:ElmaKyune:20220331191354p:plain

マテリアル設定中

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を変化させ、「右手を頭上の帽子に持ってきたときに、帽子を手に持つ・頭にかぶる状態を切り替えられる」状態にする。

 

今回作ったものの動作例がこれ。

f:id:ElmaKyune:20220311211324g:plain

動作

工程

VRC Contact Senderの追加

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

f:id:ElmaKyune:20220308204859p:plain

VRCContactSender

VRC Contact Receiverの追加

帽子のボーンにVRCContactReceiverを追加する…つもりだったが、移動させる(手に追従させる)ボーンにReceiverをつけると面倒なことが起きそうなので、帽子のボーンと同じ位置に新規でGameObjectを作成し、それにReceiverを追加した。

自分からだけ触れるようにするつもりなので、Allow Selfだけチェックをつけた。

先に設定したSenderと同じCollision Tagsを設定した。

今回は「帽子に手が触れた瞬間」にParameterが書き換わってほしいので、ReceiverTypeはOnEnterを選択。MinVelocityは初期値から変更していない。このParameterはBooleanでなくFloatしか許容してくれないようなので、Valueには1.0を入力(したら、1と表示された)。

f:id:ElmaKyune:20220308205240p:plain

VRCContactReceiver

ExParameterに同名のParameterを追加

VRC Avatar Descriptorに設定してあるExParameterを参照し、

f:id:ElmaKyune:20220308210055p:plain

ExParameter

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

f:id:ElmaKyune:20220308210132p:plain

Parameters

ExParameters動作確認

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

f:id:ElmaKyune:20220311211912j:plain

Avatar Debug Console

ここまででAvatar DynamicのContactの話は終わり。ここからは帽子を手に追従させるConstraintの話。

Constraint Sourcesの追加

帽子を固定したい階層にGameObjectを作成する。CapConstraintHeadとCapConstraintRightHandを作成した。このうち、頭用のCapConstraintHeadは先程VRCContactReceiverをつけたObjectも兼ねている。

f:id:ElmaKyune:20220308210932p:plain

Constraint Sources

Parent Constraintの追加

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

持ち方を調整したかったらこの時点でSourcesの座標とか回転を調整しておくといいかも。

f:id:ElmaKyune:20220308211308p:plain

Parent Constraint

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ウィンドウやファイルのことをあまり調べていないので、この謎の手順には納得していない。)

f:id:ElmaKyune:20220308212322p:plain

Animation

Animator Parametersの設定

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

f:id:ElmaKyune:20220308212654p:plain

Animatorタブ内

Animator Layersの設定

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

f:id:ElmaKyune:20220308213031p:plain

Layers

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

f:id:ElmaKyune:20220308213214p:plain

State

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

あまり納得していないが、他の方法がわからない以上、一旦これを利用することにした。

f:id:ElmaKyune:20220308213531p:plain

Transitions

以上で設定は終わり。

 

感想等のメモ

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