アバター改変の解説 第2回

Unity と VRChat で見た目が変わる

Unity で整えたはずの表情や体の形が、VRChat に入ると元に戻っている。その多くは、FX の Animator が BlendShape(シェイプキー)の値を書き換えているためです。なぜ書き換わるのか、どこを見て、どう直すのかを解説します。

公開 · 対象は Unity の Built-in Render Pipeline と VRChat のアバター(Avatars 3.0)です。2026年11月時点の内容です。

こんなときに読んでください

  • Unity で BlendShape を動かして表情を変えたのに、VRChat では元の顔に戻る。
  • 服に合わせて体を縮めたのに、VRChat では体が服から突き抜ける。
  • ハンドサインを変えると、表情と一緒に、体の形や頬染めまで変わる。
  • 一度ハンドサインで表情を変えると、手を戻しても表情が戻らない。

見た目が変わるおもな理由

Unity と VRChat で見た目が変わる理由は、いくつかあります。この記事では、いちばん多い 1 を詳しく扱います。

1. Animator が値を書き換える
VRChat では、アバターの Animator(とくに FX)が動き、アニメーションに書かれた値で BlendShape などを毎フレーム上書きします。Unity の編集画面では Animator は動いていません。この記事の本題です。
2. VRChat が動かす BlendShape
まばたきと口の形(Viseme)は VRChat が動かします。VRC Avatar Descriptor の Eye Look や Lip Sync に設定した BlendShape は、Unity で値を入れても上書きされます。
3. 揺れもの(PhysBone)
Unity の編集中は揺れものが動かないので、髪やスカートは作ったときの形のままです。VRChat では重力などで形が変わります。Unity で再生すると動きます。
4. 明るさと色
Unity のシーンのライトと、ワールドのライトは違います。ワールドによって、明るさや色、影の出方が変わります。
5. 見る人の設定と機器
見る人のセーフティ設定でシェーダーが止められると、別の見た目になります。Quest やスマホでは、対応版のアバターか、代わりの姿で見えます。
6. 描く順番
半透明のパーツは、ワールドの半透明の物と重なると、描く順番で見え方が変わります。 第1回 Render Queue

Unity の編集画面では、Animator が動いていない

Unity で再生していないときに見えているのは、Skinned Mesh Renderer の BlendShapes の欄に入れた値そのものです。Animator は動いていません。

VRChat でアバターを読み込むと、Animator が動き出します。Animator は、いま入っているステートのアニメーション(クリップ)に書かれた値を、毎フレーム上から書き込みます。Unity で入れた値は、そのたびに上書きされます。

つまり、どこかのクリップに書かれている BlendShape は、Animator が値を決めます。Skinned Mesh Renderer の値がそのまま見えるのは、Animator がその BlendShape に何も書かないときだけです。

  1. Unity で入れた値Skinned Mesh Renderer の eye_smile = 60
  2. VRChat で読み込むAnimator が動き出す
  3. FX の Idle ステートクリップが eye_smile = 0 と書く
  4. 見た目eye_smile = 0(Unity と違う)
再現図:Unity の Inspector(Skinned Mesh Renderer の BlendShapes)。名前は例です
  1. 表情を変えたくて入れた値です。FX のクリップが eye_smile を書いていると、VRChat ではその値になります。
  2. 服に合わせて体を縮めた値です。服のオンオフのクリップが shrink_chest を書いていると、VRChat ではその値になります。

Write Defaults で変わること

Animator は、コントローラーのどこかのクリップに出てくるプロパティを、すべて受け持ちます。いまのステートのクリップにそのプロパティがあれば、その値を書きます。クリップに無いときに何を書くかを決めるのが、ステートの Write Defaults です。

Write Defaults が ONWrite Defaults が OFF
クリップに書いてあるクリップの値クリップの値
クリップに書いていない既定値(読み込んだときの値。つまり、アップロードしたときに Unity で入れていた値)何も書かない(直前に書かれた値が残る)

Write Defaults が OFF のアバターでは、ハンドサインで変えた表情が残らないように、何もしていないとき(Idle)のステートに、表情の BlendShape をすべて 0 にするクリップを置いていることがよくあります。このクリップが、Unity で入れた値も 0 に戻します。

同じ BlendShape を複数のレイヤーが書くときは、下にあるレイヤーが優先されます。

動かして確かめる

Unity で入れた値、Write Defaults、いまのステートを変えて、VRChat での見た目がどうなるかを見てみてください。値を変えると、アップロードし直したものとして最初から数えます。

Unity(編集中)

eye_smile 60

VRChat

eye_smile 0

60

Write Defaults
いまのステート

いまのステートのクリップが eye_smile を 0 と書いているので、Write Defaults に関係なく 0 になります。

Unity と違う見た目です(Unity では 60、VRChat では 0)。

よくある困りごとと直し方

変えた表情が元に戻る

起きること
Unity で目や口の BlendShape を動かして、いつもの表情を変えた。VRChat では元の表情に戻る。
原因
FX の Idle ステート(何もしていないときのステート)のクリップが、その BlendShape を書いています。
直し方
そのクリップの値を、Unity で入れた値に変えます。Write Defaults が ON なら、クリップからその行を消す方法もあります。

縮めた体が服から突き抜ける

起きること
服に合わせて体の BlendShape(縮小用)を動かした。VRChat では体が元の形に戻り、服から突き抜ける。
原因
服をオンオフするクリップが、体の縮小の BlendShape も書いています(たとえば服がオンのとき 100、オフのとき 0)。いまのステートのクリップの値が使われます。
直し方
服のオンオフのクリップで、縮小の値を合わせます。服がオンのときのクリップに、Unity で入れた値を書きます。

ハンドサインで関係ないところまで変わる

起きること
ハンドサインで表情を変えると、体の形や頬染めまで変わる。
原因
表情のクリップに、表情と関係ない BlendShape の行が入っています。
直し方
表情のクリップから、関係ない行を消します。Write Defaults が OFF のときは、消したあとに値が残らないかも確かめます。

表情が戻らない

起きること
ハンドサインで表情を変えたあと、手を戻しても表情が戻らない。
原因
Write Defaults が OFF で、Idle のクリップにその BlendShape が無いため、ハンドサインで書いた値が残っています。
直し方
Idle のクリップに、その BlendShape をいつもの値で書く行を足します。

原因のクリップを探す

まず、Unity で再生して、VRChat と同じことが起きるかを見ます。VRChat Creator Companion から入れられる Gesture Manager を使うと、Unity で再生したときに Animator が動き、ハンドサインも試せます。再生して値が戻れば、原因は Animator です。

  1. Hierarchy でアバターを選び、Inspector の VRC Avatar Descriptor の「Playable Layers」で、FX に入っているコントローラーを確かめます。
  2. そのコントローラーをダブルクリックして、Animator ウィンドウで開きます。左の Layers に、レイヤーが並びます。
  3. レイヤーを1つずつ選び、オレンジ色のステート(最初に入るステート)をクリックします。Inspector の Motion に、そのステートのクリップが出ます。
  4. クリップを選び、Animation ウィンドウ(Window → Animation → Animation)で中身を見ます。Body : Blend Shape.eye_smile のような行があれば、そのクリップがその BlendShape を書いています。
  5. ハンドサインやメニューで入るステートも、同じように見ます。
再現図:Unity の Animation ウィンドウ(Idle のクリップの中身)。名前は例です
  1. Unity で 60 にした eye_smile を、このクリップが 0 と書いています。VRChat で Idle にいる間は、eye_smile は 0 になります。
  2. 表情と関係ない体の BlendShape が入っていることもあります。Write Defaults が ON なら、この行を消すと Unity で入れた値に戻ります。

直し方

  1. 直す前に、元に戻せるようにしておきます。クリップを複製しておくか、アバターのフォルダを書き出しておきます。
  2. 原因のクリップを Animation ウィンドウで開き、その BlendShape の行の値を、Unity で入れた値に変えます。キーが2つ以上あるときは、すべて変えます。
  3. 書かなくてよい BlendShape なら、その行を右クリックして Remove Properties で消します。Write Defaults が ON なら、Unity で入れた値が使われるようになります。OFF のときは前の値が残ることがあるので、消さずに値を直します。
  4. Gesture Manager で再生して、ハンドサインやメニューを一通り試し、値が戻らないかを確かめます。
  5. アップロードして、VRChat でも確かめます。

気をつけること

  • Unity で BlendShape を変えるだけでは、Animator が書く値には勝てません。服を着せるツールなどで BlendShape を変えたときも同じです。
  • 表情を作るツールを使っているときは、ツールの側で、いつもの表情を変えます。FX を直接直しても、ツールで作り直すと戻ります。
  • アバターの更新を入れると、直したクリップが元に戻ることがあります。更新のあとは、もう一度確かめてください。
  • 同じコントローラーの中で、Write Defaults の ON と OFF を混ぜないでください。どの値が残るのか分かりにくくなります。

まとめ

  • Unity の編集画面では Animator が動いておらず、VRChat では動きます。
  • どこかのクリップに書かれている BlendShape は、Unity で入れた値ではなく、Animator が値を決めます。
  • クリップに無いときは、Write Defaults が ON なら Unity で入れた値、OFF なら直前の値になります。
  • Gesture Manager で再生して確かめ、原因のクリップの値を直します。

アバター改変の解説の一覧