この記事では、アバターを最適化(軽量化)するのに役立つ「Avatar Optimizer」というツールの使い方を説明します。アバターをUnityにインポートし、服を着せた状態からスタートします。そこまでの手順について知りたい方は、こちらの記事をご覧ください。
なお、上の記事からの続きとして、狛乃くんに「ゆるふわトラッド」(作者:はるんち)という衣装を着せたところから始めます。
アバターランクと、最適化することのメリットについて
VRChatのアバターには「パフォーマンスランク」というものがあります。これは、アバターの負荷がどれくらいかを示す指標です。Excellent > Good > Medium > Poor > Very Poor の5段階に分かれており、「Excellent」のアバターの負荷が最も軽く、「Very Poor」が最も重いという順番になっています。

VRChatのイベントの案内に「Very Poorのアバターは使わないでください」といった注意書きを見たことがあるかもしれません。イベントの進行に支障をきたすので重すぎるアバターは避けてください、というわけですね。
でも、クオリティの高いアバターや、いろいろ改変したアバターは、大体「Very Poor」になってしまうかと思います。「Very Poor」のアバターは、ただ重いというだけでなく、悲しいことに、mobile版のVRChatを使っている人からはそもそも見えません。
そのため、見た目をほとんど変えることなくアバターを軽量化するために、「アバター最適化」という作業を行います。
導入方法
Avatar Optimizerをインストールする方法については、こちらの記事の「ツールを追加・管理しよう」をご覧ください。
Manual Bakeのやり方
Avatar Optimizerは “非破壊な” ツールです。つまり、VRChatにアバターをアップロードするちょうどそのときに、自動で最適化が実行されます。このため、VRChat以外の用途、例えば “clusterで使うためにVRM形式でアバターをエクスポートしたい” といった場合には、手動で最適化を実行して、最適化されたアバターをエクスポートする必要があります。
そんなときに役立つのが「Manual bake avatar」という機能です。実際に使ってみましょう。
アバターのルートを選択し、「Tools」>「MDM Framework」>「Manual bake avatar」の順にクリックします。
「Komano_Kaihen(Clone)」が増えました。これが、最適化が実行された後のデータです。
コンポーネント1つでアバター最適化を自動設定
「AAO Trace And Optimize」というコンポーネントを使用すると、次のような最適化が自動で行われます。詳細については、Avatar Optimizerの公式ドキュメントをご覧ください。
- 使用していないBlendShape(シェイプキー)の除去
- 使われていないPhysBone等の削除
- アニメーションしたりPhysBoneで揺らしたりすることのないボーンの統合
- 一緒に切り替えていたり、切り替えることがなかったりするメッシュ同士の統合
では、実際に「AAO Trace And Optimize」を使ってみましょう。
アバターのルートを選択し、「Inspector」画面の「Add Component」をクリックします。

「AAO Trace And Optimize」を検索して見つけ、クリックします。

これで終わりです。めちゃくちゃ簡単ですね。

Actual Performance Windowでパフォーマンスをチェック
「Actual Performance Window」という機能を使うと、アバターのパフォーマンスを確認することができます。例えば、最適化する前と後に実行して、どれくらい軽量化されたかをチェックすることができます。
導入方法や使い方については、こちらの記事の「ツールで最適化した結果を「Actual Performance Window」で試そう!」をご覧ください。
試しに、「AAO Trace And Optimize」を付ける前と後で比べてみましょう。

ばっちり軽量化されていますね。
ポリゴン削減
ここでは、ポリゴンの削減に役立つコンポーネントを紹介します。
Remove Mesh By BlendShape
「AAO Remove Mesh By BlendShape」を使えば、服の下などに隠れている部分を削除することができます。
アバターに衣装を着せるときに、体が衣装の上に出てこないように(貫通しないように)、BlendShapesでパーツを絞ることがあるかと思います。
(Before)

(After)

「AAO Remove Mesh By BlendShape」というコンポーネントでは、ただ絞って小さくするのではなく、完全に削除することができます。
実際にやってみましょう。「Hierarchy」で、削除したい部分があるオブジェクト(例として「Karada」)を選択し、「Inspector」画面の「Add Component」をクリックします。

「AAO Remove Mesh By BlendShape」を検索して見つけ、クリックします。

削除したいものにチェックを入れれば完了です。削除する際は上のチェックマークを押して、変化のプレビューを確認できるようにしましょう。

Remove Mesh By Mask
「AAO Remove Mesh By Mask」というコンポーネントでは、テクスチャを塗りつぶすことによって、細かな部分を削除することができます。
この記事では例として、アホ毛(?)を消してみようと思います。

「Hierarchy」で、削除したい部分があるオブジェクト(例として「Hair」)を選択し、「Inspector」画面の「Add Component」をクリックします。

「AAO Remove Mesh By Mask」を検索して見つけ、クリックします。

「Hair」にはマテリアルが2つ含まれているようです。

マテリアルは、「Skinned Mesh Renderer」の「Materials」を広げると確認できます。

0番に「Hair」が、1番に「Alpha」が設定されていることが分かります。

今回消したいアホ毛が関係するのは0番の「Hair」のようですので、「0番のマテリアルスロットに適用」にチェックを入れます。

「作成」をクリックします。

作成する新しい画像を保存するための画面が出てきます。

アバターのフォルダの中にある、テクスチャを保存しているフォルダを探し、好きな名前を付けて「保存」をクリックします。今回は “Hair2” にしてみました。

「編集」をクリックします。

「AAO マスクテクスチャエディター」が表示されますので、削除したい部分を塗りつぶしていきます。

操作方法:
- 塗りつぶし:左ドラッグ
- 移動:右ドラッグ、またはShift + 左ドラッグ
- ズームイン/アウト:スクロール
- ブラシサイズの変更:Shift + スクロール
どこが削除されるのかをリアルタイムで確認しながら塗りつぶしていくことができます。

塗りつぶし終わったら、「保存する」をクリックします。

保存したらウィンドウを閉じます。

Remove Mesh in Box
「Remove Mesh in Box」というコンポーネントは、広い範囲を一気に削除したいときに便利です。このコンポーネントでは、箱の内側または外側をまとめて消すという方法でポリゴンを削除します。
実際にやってみましょう。例として、カーディガンの右袖を消してみます。
削除したい部分があるオブジェクト(例として「cardigan」)を選択し、「Inspector」画面の「Add Component」をクリックします。

「AAO Remove Mesh By Box」を検索して見つけ、クリックします。

「Edit This Box」をクリックします。

箱の外側を削除する方法にしたいときは、「削除するポリゴン」を「箱の外側」に変更します。この記事では、「箱の内側」のパターンで説明していきます。

箱を移動させたり、回転させたり、箱の大きさを変えたりして、ポリゴンを削除します。

操作方法:
- 移動:「Scene」で矢印をドラッグする。またはコンポーネント内の「Boxes」の数値を変更する
- 回転:「Scene」で半円の線をドラッグする。またはコンポーネント内の「Boxes」の数値を変更する
- 大きさの変更:コンポーネント内の「Boxes」の数値を変更する
半袖になりました。

PhysBoneの結合による最適化
ここでは、PhysBoneを最適化する方法を紹介します。いらない部分を削除していた「ポリゴン削除」とは違い、ここでは、同じものをまとめるという作業によって最適化を図ります。使うのは、「AAO Merge PhysBone」というコンポーネントです。
「PhysBone」とは、“揺れもの用の機能” のことです。アバターの中で揺れる部分にはそれぞれ、この「PhysBone」が付けられており、揺れ方などが設定されています。(PhysBoneについて詳しくは、VRChatの公式ドキュメントをご覧ください)

同じ設定のPhysBoneが別々の箇所に付けられている場合があり、「AAO Merge PhysBone」では、それらを統合することができます。
なお、1つのPhysBoneに統合するため、掴むといった動きが同時に1つしかできなくなります。例えば耳のPhysBoneを統合した場合、左右それぞれを掴むことができないといった感じです。
この記事で例として使っているアバターでは、両耳に同じ設定のPhysBoneが付いていました。「AAO Merge PhysBone」を使ってまとめてみます。ただ、その前に、そもそもどのオブジェクトにPhysBoneが付いているのかを調べる方法を紹介します。
「VRChat SDK」>「Show Control Panel」の順にクリックして、「VRChat SDK」ウィンドウを開きます。

「Builder」タブを下にスクロールして、「Validations」の中にある、PhysBoneに関するメッセージを探し、「Select」をクリックします。

選択されたオブジェクトがありますね。このオブジェクトにPhysBoneが設定されています。

では本題に戻り、「AAO Merge PhysBone」を使って両耳のPhysBoneをまとめてみましょう。まず、アバターのルートを右クリックし、「Create Empty」をクリックします。

「GameObject」という名前のオブジェクトが追加されますので、分かりやすい名前に変更します。この記事では、“Merge PB” という名前にします。

「Inspector」ウィンドウで、「Add Component」をクリックします。

「AAO Merge PhysBone」を検索して見つけ、クリックします。

作業しやすいようにこの画面をロックしておきたいと思います。「Inspector」画面の右上にあるマークをクリックします。

画面がロックされました。

「コンポーネント」の左の「▶」をクリックして広げます。

「追加する要素」の右の「None (VRC Phys Bone Base)」に、統合したいPhysBoneが付いているオブジェクト(例として「Ear.L」と「Ear.R」)をドラッグアンドドロップします。

これで完了です。

作業が終わったら、ロックを解除しておきましょう。
