跳到正文
Qiita · Unity 开发社区· 来源· bet7y·· 2 小时前AI 评分8

VRChat 中利用 Animation Parameter 与 Expression Parameter 类型不一致(Parameter Mismatching)的理由

型の不一致 (Parameter Mismatching) を使う理由

正文 · 原文

はじめに

アバターギミックにおいて、Animation Parameter (以下、AnimParam) と Expression Parameter (以下、ExParam) が、Unity にて異なるデータ型に設定されることがあります。いわゆる Parameter Mismatching です。

今回は「なぜ、わざわざ そのような分かりづらい設定にするのか。その 意図 は何なのか」という積極的な理由を解説します

その際、よく聞く「なぜ、そのように設定しても 問題なく 動作するのか」という消極的な理由や、周辺事項にも触れていきます

また今回の解説では、下の記事で解説している実装を例にしているので、先にこちらを読むことをお勧めします

結論

Synced Bits を節約するため です。
これは ExParam の Inspector 上部に表示されている
image.png
のことです。

現在の VRChat は同期パラメータのデータ量を合計 256bit までに制限しています。
Float 型の Synced Bits は 8 であり、Bool 型の Synced Bits は 1 です。
そのため、ExParam で Bool 型として設定しておくことで、Synced Bits を 7 も削減できます。

思ったよりしょうもない理由で拍子抜けしましたか?
しかしこれは、重要な思考の整理を含みます。

つまり「ExParam を Bool 型にするのは 『トグルに使うから』ではない」ということです。
なぜなら、ExMenu でトグルの Parameter に Float 型のパラメータを設定すれば、Float 型の 1 (いわゆる 1.0f) を指定することができ、
image.png
トグルが ON なら Float 型の 1 が設定され、トグルが OFF なら Float 型の 0 が設定されるからです

また VRChat 公式によれば、リモート同期される Float パラメータは -1, 0, 1 の値を正確に表せます。1
したがって「Bool 型から Float 型への Parameter Mismatching を使わないと、AnimParam に正確な 1.0f を渡せない」というわけではありません

以下、消極的な理由と周辺事項の説明に移ります

Float パラメータを Bool として設定していい理由

「本来は Float 型である AnimParam を ExParam で勝手に Bool 型として宣言していいの?」と思う方もいるでしょう。

Bool 型の ExParam に Bool 型の true が設定されるとき、Float 型であり同名の AnimParam にはFloat 型の 1 が設定されます。
逆に、ExParam に false が設定されるとき、AnimParam には Float 型の 0 が設定されます。

したがって、ExParam が Bool 型として設定されていても、Float 型の AnimParam には Foat 型の 0 や 1 が正しく渡されます。
(その他の型の組み合わせについては、VRCSchool の解説をご覧ください)

これは、プログラミングに慣れた方には「暗黙的な型変換」として知られるものと同じ挙動です。しかし、正確には別物です。

Unity の UI において Bool, Int, Float を見ることはありますが、VRChat 内部では SByte という単一の型で処理されています。
Bool でも Int でも Float でも、VRChat 内部では SByte で処理されており、SByte から SByte への変換しか起こっておらず、「型変換」はされていません。
Float から Bool へ「暗黙的な型変換」が行われたように見えるのは、あくまでも Unity のバックエンド上です。2

余談ですが、VRChat 公式によれば、同期 Float パラメータは -1, ..., 0, ..., 1 の値を 1/127 の精度で同期しています。1
本来 32bit で値を表せるはずの Float が -127/127, -126/127, ..., 127/127 の 255 通りの値しか取れないことは、SByte (符号付き 8bit 整数) が $2^8 = 256$ 通りの値しか取れないことに一致します

AnimParam に 0 か 1 の値だけをとらせたい理由

「AnimParam は Float 型だから本来であれば広い範囲の値をとれるはずだが、この設定をすると 0 か 1 以外の値をとれなくなるけどいいの?」と思う方もいるでしょう。

まず、BlendTree「BoxCollider」は 1D BlendTree であるため、Parameter「IsBoxCollider」の値によって、アタッチされた Animation Clip がブレンドされて再生されます。

1D BlendTree を理解するために、アタッチされた Animation Clip が次の 2 つである場合を考えます

Animation Clip 名 アタッチされている側の Threshold Animation Clip の内容
Constant_Zero.anim 0 Animation Clip 全体を通して、あるプロパティに 0 を設定する
Constant_One.anim 1 Animation Clip 全体を通して、あるプロパティに 1 を設定する

このとき次の画像のように、Parameter「IsBoxCollider」の値が 0.3 のとき
image.png
赤いバーの位置における青い部分の高さの割合だけ、それぞれの Animation Clip が再生されます。正確には、以下のように加重平均された値が再生されます

\begin{aligned}
    \text{実際に再生される値} 
    &= (1 -\text{IsBoxCollider})\times\text{Value}_\text{Constant_Zero}
    + \text{IsBoxCollider}\times\text{Value}_\text{Constant_One} \\
    &= (1 - 0.3)\times 0 + 0.3\times 1 \\
    &= 0.3
\end{aligned}

これを「ブレンドする/される」と言います

1 つの Animation Clip 内で時間によって値が変化する場合
(SeatPosition_Backward2Forward.anim を使った場合など) は
一般に加重平均した結果も時間によって変化しますが、

今回は各 Animation Clip の中で全体を通して値が一定である状況を仮定しているので、実際に再生される値 (加重平均した結果) は時間に依りません

翻って、今回使っている Animation Clip では、ブレンド結果は時間に依りません

Animation Clip 名 アタッチされている側の Threshold Animation Clip の内容
BoxCollider_Off 0 Animation Clip 全体を通して、Box Collider コンポーネントがオフになる
BoxCollider_On 1 Animation Clip 全体を通して、Box Collider コンポーネントがオンになる

トグル「椅子表示」の内部実装である BlendTree「BoxCollider」では、Box Collider コンポーネントがオンとオフの 2 つの状態のみを表してほしいです。

このことから、Parameter「IsBoxCollider」は両端の値、つまり「0 または 1」のみを取ってほしいです。
逆に中間の 0.3 などの「ブレンド」が発生する値はとってほしくありません。

したがって、Float 型の AnimParam が 0 または 1 の値のみを取るのは望ましいことです

結論の支持

ExParam が Bool 型であることで、Synced Bits を節約できます

ExParam を Bool 型にすることで true か false の値のみ取るようになり、
Float 型の AnimParam には 1 か 0 の値のみが渡されるので、
ブレンドが発生せずに 2 つの状態のみを表す「トグル」として問題なく使えます。

おわりに

普段「型の不一致」を利用されている方の中にも、「トグルに使うから ExParam を Bool 型にする」と思っていた方もいたのではないでしょうか。

この記事が、みなさんの思考整理に役立ったなら幸いです

  1. VRChat. "Animator Parameters". VRChat. 2026. https://creators.vrchat.com/avatars/animator-parameters/#parameter-types, (2026-11-05) ↩ ↩2

  2. Jellejurre、JustSleightly. "Expression Parameter Mismatching". VRCSchool. 2024. https://vrc.school/docs/Other/Parameter-Mismatching/#ea79f2b19900472cb27828cb4b9d193c, (2026-11-05) ↩

来源:Qiita · Unity 开发社区 · qiita.com