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 に何も書かないときだけです。
- Unity で入れた値Skinned Mesh Renderer の eye_smile = 60
- VRChat で読み込むAnimator が動き出す
- FX の Idle ステートクリップが eye_smile = 0 と書く
- 見た目eye_smile = 0(Unity と違う)
▼ BlendShapes
- 表情を変えたくて入れた値です。FX のクリップが eye_smile を書いていると、VRChat ではその値になります。
- 服に合わせて体を縮めた値です。服のオンオフのクリップが shrink_chest を書いていると、VRChat ではその値になります。
Write Defaults で変わること
Animator は、コントローラーのどこかのクリップに出てくるプロパティを、すべて受け持ちます。いまのステートのクリップにそのプロパティがあれば、その値を書きます。クリップに無いときに何を書くかを決めるのが、ステートの Write Defaults です。
| Write Defaults が ON | Write Defaults が OFF | |
|---|---|---|
| クリップに書いてある | クリップの値 | クリップの値 |
| クリップに書いていない | 既定値(読み込んだときの値。つまり、アップロードしたときに Unity で入れていた値) | 何も書かない(直前に書かれた値が残る) |
Write Defaults が OFF のアバターでは、ハンドサインで変えた表情が残らないように、何もしていないとき(Idle)のステートに、表情の BlendShape をすべて 0 にするクリップを置いていることがよくあります。このクリップが、Unity で入れた値も 0 に戻します。
同じ BlendShape を複数のレイヤーが書くときは、下にあるレイヤーが優先されます。
動かして確かめる
Unity で入れた値、Write Defaults、いまのステートを変えて、VRChat での見た目がどうなるかを見てみてください。値を変えると、アップロードし直したものとして最初から数えます。
Unity(編集中)
eye_smile 60
VRChat
eye_smile 0
いまのステートのクリップが 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 です。
- Hierarchy でアバターを選び、Inspector の VRC Avatar Descriptor の「Playable Layers」で、FX に入っているコントローラーを確かめます。
- そのコントローラーをダブルクリックして、Animator ウィンドウで開きます。左の Layers に、レイヤーが並びます。
- レイヤーを1つずつ選び、オレンジ色のステート(最初に入るステート)をクリックします。Inspector の Motion に、そのステートのクリップが出ます。
- クリップを選び、Animation ウィンドウ(
Window → Animation → Animation)で中身を見ます。Body : Blend Shape.eye_smileのような行があれば、そのクリップがその BlendShape を書いています。 - ハンドサインやメニューで入るステートも、同じように見ます。
- Unity で 60 にした eye_smile を、このクリップが 0 と書いています。VRChat で Idle にいる間は、eye_smile は 0 になります。
- 表情と関係ない体の BlendShape が入っていることもあります。Write Defaults が ON なら、この行を消すと Unity で入れた値に戻ります。
直し方
- 直す前に、元に戻せるようにしておきます。クリップを複製しておくか、アバターのフォルダを書き出しておきます。
- 原因のクリップを Animation ウィンドウで開き、その BlendShape の行の値を、Unity で入れた値に変えます。キーが2つ以上あるときは、すべて変えます。
- 書かなくてよい BlendShape なら、その行を右クリックして
Remove Propertiesで消します。Write Defaults が ON なら、Unity で入れた値が使われるようになります。OFF のときは前の値が残ることがあるので、消さずに値を直します。 - Gesture Manager で再生して、ハンドサインやメニューを一通り試し、値が戻らないかを確かめます。
- アップロードして、VRChat でも確かめます。
気をつけること
- Unity で BlendShape を変えるだけでは、Animator が書く値には勝てません。服を着せるツールなどで BlendShape を変えたときも同じです。
- 表情を作るツールを使っているときは、ツールの側で、いつもの表情を変えます。FX を直接直しても、ツールで作り直すと戻ります。
- アバターの更新を入れると、直したクリップが元に戻ることがあります。更新のあとは、もう一度確かめてください。
- 同じコントローラーの中で、Write Defaults の ON と OFF を混ぜないでください。どの値が残るのか分かりにくくなります。
まとめ
- Unity の編集画面では Animator が動いておらず、VRChat では動きます。
- どこかのクリップに書かれている BlendShape は、Unity で入れた値ではなく、Animator が値を決めます。
- クリップに無いときは、Write Defaults が ON なら Unity で入れた値、OFF なら直前の値になります。
- Gesture Manager で再生して確かめ、原因のクリップの値を直します。