
【VRChat】【Unity】かける式お着換え実装法(Modular Avatar+Avatar Optimizer+Prefab Variant+lilAvatarUtils)
・このNoteは以下のNoteの応用編になっているので先にこちらの閲覧を推奨
上のNoteではデフォルト服の上から着せ替え服をModular Avatar(以下MA)+Anatawa12's Avatar Optimizer(以下AAO)で着せて、後からデフォルト服をEditorOnlyにして消去するという手法だったが、MA+AAOによる着せ替えは色々と応用が利くので、以下に筆者の現行(2024.2時点)のお着換え実装法を記す。lilAvatarUtilsについても記載。
1. MAの設計思想

Unityを初めて触る人にはPrefabという言葉に馴染みのない人が大半だとは思うが、要はzipファイルみたいなものである。(上の画像中ではあえて.zipという表現にしている)
今までアバターに対して着せ替えを実装する際は、着せ替え服のPrefabをUnpackして、アバター本体のArmatureへ服のボーンを合成する、という手法がメインだった(キセテネとかのツールではこの工程を自動で行ってくれていた)。服というzipファイルを解凍して数十個のアバターフォルダへ振り分ける作業みたいなものである。

服のボーンを分解(Unpack)してアバター素体の同名ボーンへ合成する為、基本的には不可逆工程になっている。
対してMAによる着せ替えでは、アバター素体と服をPrefabのまま合成している。


手順的にもPrefabのままヒエラルキーに置いてSetup Outfitするだけなので、楽になっている。それに加えて、MAによる着せ替えは着せ替え以外のギミックを同時に付与できる所に長所がある。

MAはModularの名の通り、アバター(素体)に対して部品を複数付けてアバター本体を完成させるイメージで、服もその部品の一つ、と解釈する。ロボットのパーツを組み合わせて本体を完成させる感じか。
また、服をMAで導入する際に、服自体の着換えギミック(例えば靴やソックス・上着等の着脱とか)も同時に導入できるのがポイント。

Add Componentでこの順に追加する。
MA Merge Animator: 選択したAnimator Controllerにレイヤーを追加できる。基本的にはFX Layerに対して追加する。
MA Parameters: 同期パラメータであるExpression Parametersを追加できる。
MA Menu Installer: あらかじめアバター素体側のExpression Menuに空メニュー(何も登録されてないメニュー)を用意しておき、そこにMA Menu Installerで後付けメニューを追加する。
以上のMAコンポーネントを服のRootにつけておくと、服をMAで導入すると同時に服の着脱ギミック等も同時にExpression Menuへ追加できる。
またこれは服に限らず、アバターギミック全般に対しても同様なことが可能なので、アバターギミックを販売する際に、導入方法がアバターのRootへ配置してください、で終わるので説明が楽になっている(わざわざアバター素体のFX LayerやExpression Parametersを改変する必要が無い)。


2024.5.20追記:要点だけまとめたものを別記事にアップしました
※2024.12追記 ↑のやり方のうちON/OFFのみのギミックはさらに楽な実装方法が可能になったのでこちらを参照
2. MA+Prefab Variant
MAによる着換え法は、Prefab Variantと組み合わせるとさらに管理がしやすくなる。



特に単一アバターを複数の着せ替え実装して使うような人に対して非常に有用な運用方法で、ヒエラルキーにアバター素体を置く際に、アバター素体のPrefabそのものではなく、そのPrefabのVariantを作成し、そのVariantをヒエラルキーに配置、そのVariantに対してMAで着せ替えを行う。そうするとアバター素体に仕込んだギミック(表情改変やアクションエモート等の共通で使用したいギミック)を複数の着せ替えに使いまわすことが可能になり、アバタープロジェクト1つで複数の着せ替えが実装できる。その上で後述するメリットが出てくる。

表情改変やアクションエモート等は基本的には大半の着せ替えで使用したい共通ギミックではあるので、導入アセットのPrefabには手を加えずにそのVariantを作成し、Variantにたいしてギミックを実装する。その上でさらにそのVariantを作成(VariantのVariant)し、それに服を実装する。
この構造にしておくメリットは、後で共通ギミックを一斉に自動追加できる所にある。


例えば着せ替えアバターを複数実装した後で、Prefab本体に更新が入ったり、アバター共通ギミックを後付けしたくなった場合、Unpackしていた方法だと着せ替えアバター全てに対して更新作業を行わなければならなくなるが、Prefab Variantを使用する方法なら、Prefab Variantに対してPrefab編集モードを使用してPrefab Variantの更新を行うと、その更新が子のVariant全てに対して自動で適用される。
なので、上の図なら、濃青色の改変ベースに対してPrefab編集モードで共通ギミックを足した場合、水色のコピー全てに対して自動で共通ギミックが足される。あとはアバターをそのままアップロードするだけで更新が完了する。

1アバター1プロジェクト複数シーン構成で、1シーンには服1着。
一番上のシーンが改変ベースで、あとのシーンはお着換え差分のVariant。
編集中のシーンのみActiveで、それ以外のシーンはUnload状態にしている。
上の筆者のラスクちゃんプロジェクトの例だと、一番上のベースPrefab Variantにアバターギミックを足すとその下のお着換え差分全てにギミックが自動で反映されるので、あとはGesture Managerで動作確認したあとアップロードするだけの状態にある。
3. MA+AAO+lilAvatarUtilsによるアバターのお手軽軽量化
3-1. MA Mesh SettingsとAAO Trace And Optimize

アバターのRootに付ける。設定値は画像の通りで基本OK。
MA Mesh Settings: Anchor OverrideとBoundsの設定をアバター全体で統一する。服と肌で光の当たり具合が違うとか、見る角度によってアバターの服が消える(脱げる)のを防ぐ。
Boundsの設定だが、通常サイズのアバターは上の画像で基本OK、低身長アバターでOVRによって浮く可能性のある場合は移動する可能性のある方向に対して広く設定する。


Boundsを広く設定する理由だが、OVRによって座標移動した場合、アバターの見た目が移動してるだけでワールドの地形等に対するCollider判定は移動してないからである。Bounds判定も同様。(2023.09時点で確認している)

OVRで長い距離を移動した場合、Boundsの判定が移動していない為Boundsの判定枠をはみ出してしまう。その状態で他の人が近寄って眺めた場合、他の人の視点からはBoundsの判定枠が視界の外に行ってしまう為、間近で眺めているにもかかわらずカリングされて不可視になってしまう。なおMA Mesh Settings不使用でBoundsの判定枠を素体と服で別々に設定している場合、真正面に居るにも関わらず服だけカリングされる(=脱げる)可能性がある(筆者体験済)。

この状態ならOK。低身長アバターを使用する場合は特に注意を要する。
なお広く取りすぎると視界外でもカリングされずに他の人の描画負荷上昇の要因になるのでほどほどに。
AAO Trace And Optimize: アバターRootに付ける。基本的には項目に表記してある通りだが少し補足。

BlendShapeを自動的に固定・削除する:最近のアバターにはお着換え差分が実装しやすい様にいくつもの体型調整BlendShapeキーが搭載されていたり、表情改変用に数百種類のBlendShapeキーが搭載されているものもあるが、BlendShapeキーは基本的に存在しているだけで処理が多くなる(=重くなる)。体型調整用のシェイプキーはVRChatのゲーム中でずっと0のままというキーも少なくない。そのようなシェイプキーをアップロード時に除外してくれて負荷軽減してくれる(アップロード終わると元に戻る)。アニメーションで使用しているキーは削除しない。基本的につけ得。
PhysBoneの設定を最適化する:お着換え差分をデフォルト服を消す形で実装した場合、元のデフォルト服のPhysbone設定はメッシュだけ消してもそのまま残っており、そのままではお着換え差分のPhysbone設定+デフォルト服のPhysbone設定で二重にPhysbone計算を行っている状態になる(特に元のデフォルト服は「無」を揺らしている状態になりかなり無駄な負荷になる)。この「無」を揺らす可能性のあるPhysboneを見つけ出してアップロードから除外してくれる(個別にEditorOnlyで除外しておいた方が無難といえば無難なのだが)。
3-2. lilAvatarUtils
アバター軽量化でお手軽にできる部分として、テクスチャの設定がある。ツールとしてlilAvatarUtilsを使用する。



テクスチャ設定。アバターに使用されているテクスチャ一覧が表示される。デフォルトだと4Kテクスチャ(4096×4096)は赤文字で表示。
テクスチャのサイズはVRAM使用量に直結する為、着せ替え衣装を導入する場合は必ず確認すること(筆者の改変アバターは基本的に2Kサイズ以下/合計100MB未満に落としている)。普段人数の少ないインスタンスで活動している場合はさほど気にする必要は無いが、30人を超えるようなインスタンスで活動するような場合は他の人の負荷へ与える影響が大きくなってくるので、4Kテクスチャを盛ったアバターを使用する場合は「負荷が大きい」という認識を頭の片隅に入れておいた方が無難。1Kの4倍→2K、2Kの4倍→4Kである(つまり4Kは1Kの16倍)。

マテリアル一覧については、例えば色変え改変時に改変前のマテリアルが残っている時の確認(設定変え忘れている項目の有無)等の用途に使える。また半透明系に関するトラブルが発生した場合にレンダーキューの設定一覧が出るため、その数値の確認目的にも使える。


ライティング設定は要確認項目で、暗い場所での見え方のチェック(明るさの上限・下限の設定値確認)や、フォールバックシェーダー(Safetyでシェーダー設定が無効化された時のアバターの見え方)の確認が可能。トラストランクがKnown以下の人(Trusted以外)で非フレンドの人はデフォルトのSafety設定ではシェーダーがOFFにされる(フォールバックシェーダーにされる)上に、非フレンドの人に対しては全員シェーダー設定をOFFにしている、という人も割と居るので(筆者も海外Publicインスタンス等の不意にシェーダー系視界ジャックしてくる可能性があるインスタンスに行く時は非フレンド全員のシェーダーをOFFにしている)、フォールバックシェーダー時の見え方は確認しておいた方が無難。

VRChatのゲーム中では自分の画面から確認する手段がない
3-2-1.(補足)liltoonの色調補正とフォールバックシェーダー
liltoonでは、色調補正によってお手軽に色合いを変えられる機能があるが、これはフォールバックシェーダーには反映されない(liltoon自体が違うシェーダーへ差し替えられる=色調補正が無効化される)

なので、色調補正した後は下の「焼き込み」ボタンで別テクスチャとして保存してそのテクスチャを適用する。

3-3. AAO Merge Skinned Mesh

Material Slotsも20個(Poor)


AAO Merge Skinned Mesh をアバターのRootにつけてメッシュの設定をすると、Skinned Mesh RendererとMaterial Slotをある程度統合することができる(この項目は追加するだけではダメできちんとメッシュの設定をする必要がある)。


筆者は「この服ではゲーム中でお着換えすることは無いだろう」という服を実装する場合にこのAAO Merge Skinned MeshをアバターRootへ配置している。「Animationで変化しないメッシュ群」は統合可能で、例えば
・髪が複数のメッシュになっているが特にON/OFFはしない
・アクセサリーが沢山ついていてメッシュが分かれているが、ゲーム中でアクセサリーのON/OFFはしない
・1アバター1衣装構造で、ゲーム中で着替えることは無い
等の場合は、これでメッシュを統合してしまうと軽量化できる。筆者のこのシフォンちゃんの場合は、統合後「顔(表情)のメッシュ」「髪や体と服が全て統合されたメッシュ」の2つだけに統合されている(顔のメッシュだけは表情変化で使用するので統合しない)。
ちなみにAnimationに登録されているメッシュを統合候補に入れた場合は警告表示が出て統合されない。
3-4. AAO Remove Mesh By BlendShape


着せ替えを行う際、素体の体型調整BlendShapeキーを100(面積0)にすることで干渉を防いでいるアバターの場合は、そこの部分のポリゴンのみを削除してしまう手法が使える。それがAAO Remove Mesh By BlendShapeである。プレイモード時のみ削除してそれ以外の時は削除前に戻るので安心。
特に「靴やソックスで隠れる素足の部分」「非透過タイツの場合は素足の大部分」「上半身着こむタイプの服の場合は手の部分以外の上半身も」という感じでポリゴン数が非破壊で削減できる。薄着の場合には効果が薄い。


ポリゴン数の削減は基本的にはBlender等のモデリングソフトの出番になる為、Unityのみかつ非破壊で行えるAAO Remove Mesh By BlendShapeはお手軽。▲7万以上がVeryPoor扱いなので、もう少しで▲7万を下回る、それ以外はVeryPoor未満である、という場合にこれを使うとVeryPoorを抜けられるかもしれない(上のルゼブルちゃんの場合も▲7万を下回ればMediumになる)。
4.まとめ
MAとAAOは非破壊でアバター改変&ある程度の負荷軽減を行ってくれる画期的なツールで、1年前に比べてアバター改変の方法がまるまる変わった。昔ながらの改変方法を続けている方にぜひとも試してほしい方法ではある。