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

触ると反応するギミック

頭をなでられると頬が赤くなる。しっぽをつかまれると驚いた顔になる。触れたことを Animator に伝えるのが、VRChat の Contact と、PhysBone のパラメーターです。しくみと、自分で組む手順、ほかの人からの見え方を解説します。

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

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

  • 頭をなでられたら、表情や頬染めで反応させたい。
  • 髪やしっぽをつかまれたら、表情を変えたい。
  • 触っても反応しない。自分の手でも反応してしまう。
  • 反応が、自分には見えるのに、ほかの人には見えているか分からない。

Contact のしくみ

Contact は、「触れた」ことを調べるための VRChat の部品です。Unity のふつうの当たり判定(Collider)とは別のものです。第6回 Animator のしくみで見たパラメーターに、触れているかどうかを入れてくれます。

VRC Contact Sender(送る側)
「ここにある」と知らせるだけの部品です。VRChat は、人型のアバターの頭・体・手・足・指に、Sender を自動で付けています。
VRC Contact Receiver(受ける側)
Sender が入ってきたら、Animator のパラメーターに値を入れる部品です。反応させたい場所に、自分で置きます。
Collision Tags(タグ)
Sender と Receiver の両方に、同じタグが1つでもあるときだけ反応します。大文字と小文字は区別されます。
Allow Self・Allow Others
Receiver が、自分のアバターの Sender(Allow Self)と、ほかの人の Sender(Allow Others)のどちらに反応するかを決めます。
Local Only
自分の VRChat の中だけで動かします。ほかの人の画面では動きません。そのかわり、パフォーマンスランクに数えられません。

VRChat が自動で付けている Sender には、Built-In Contact Tags のページ(新しいタブで開きます)にあるタグが付いています。よく使うのは Head(頭)、Torso(体)、Hand(どちらかの手)、HandL・HandR(左手・右手)、Finger(どれかの指)、Foot(足)です。Receiver にこのタグを入れると、ほかの人のアバターの手や指にも反応します。

自動の Sender の位置や大きさは、VRC Avatar Descriptor の Colliders の欄で調整できます。ここの Sender は、パフォーマンスランクには数えられません。

Receiver Type の選び方

Receiver が Animator のパラメーターに何を入れるかは、Receiver Type で選びます。

Receiver Typeパラメーターの型入る値向いている使い方
ConstantBool(Float・Int も可)触れている間ずっと true(1)。離れると false(0)触れている間だけ表情を変える、頬を赤くする
OnEnterBool(Float・Int も可)触れた瞬間の1フレームだけ true(1)。次のフレームで戻る触れたら1回だけ何かを始める(音を鳴らす、アニメーションを1回流す)
ProximityFloat だけ0〜1。Receiver の中心に近いほど 1 に近づく近づくほど強く変える(頬染めの濃さ、目を細める度合い)

Proximity の値は、Sender の表面から Receiver の中心までの近さです。Receiver の縁に触れたところで 0 を少し超え、Sender が中心まで来ると 1 になります。いくつも Sender が入っているときは、いちばん近いものの値になります。

OnEnter には Min Velocity を入れられます。ある速さより速く入ってきたときだけ反応させる値で、「軽く触れたときは反応せず、ぽんと叩いたときだけ反応する」ような使い方ができます。

動かして確かめる

頭の上に、半径 15 cm の球の Receiver(Collision Tags は Hand と Finger)を置いたとします。手の距離、だれの手か、Allow Self・Allow Others を変えて、Receiver Type ごとの値と、頬染めの結果を見てください。

横から見た図

顔

blush 0

25

なでている手
Receiver の Filtering
頬染めにつなぐ Receiver Type

Receiver が入れる値

  • Constant:0
  • OnEnter:0
  • Proximity:0

手が Receiver の球(半径 15 cm)の外にあります。どの Receiver Type でも 0 です。

頬染め(blush):0。頬は赤くなりません。

頭をなでると頬が赤くなるギミックを作る

頭の上に Receiver を置き、手や指が近づくほど頬が赤くなるようにします。Receiver Type は Proximity にして、近さを Motion Time で頬染めの濃さにします。Animator の組み方は第8回 メニューでオンオフするギミックを作る、Motion Time は第9回 段階で切り替える・少しずつ変えるギミックで解説しています。

1. Receiver を置く

  1. Hierarchy でアバターの中を開き、Armature の中の頭の骨(Head)を探します。名前や並びはアバターで違います(例:Armature → Hips → Spine → Chest → Neck → Head)。
  2. Head を右クリックし、Create Empty を押します。できた GameObject の名前を HeadPat にします。頭の骨の子にするのは、頭が動いても Receiver がついてくるようにするためです。
  3. HeadPat を選んだまま、Inspector の下の Add Component を押し、VRC Contact Receiver と入力して足します。
  4. Shape Type を Sphere にし、Radius を 0.1〜0.15 くらいにします。Scene ビューに球の線が出ます。Position の Y を少し上げて、球が頭のてっぺんにかぶるようにします。値はアバターの大きさで変わるので、Scene ビューで見ながら決めます。
  5. Allow Others にチェックを入れます。自分の手でなでても反応させたいときは、Allow Self にもチェックを入れます。Local Only は外したままにします(理由は下の「ほかの人にも同じに見えるか」で説明します)。
  6. Collision Tags の Add を押し、出てくる一覧から Hand を選びます。もう一度押して Finger も足します。手で入力するときは、大文字と小文字まで同じにします。
  7. Receiver Type を Proximity にし、Parameter に HeadPat と入力します。
再現図:Unity の Inspector(VRC Contact Receiver)。名前は例です
  1. 頭のてっぺんを包む大きさの球にします。
  2. ほかの人の手に反応させます。自分の手でも反応させるなら Allow Self も入れます。
  3. VRChat が手と指に自動で付けている Sender のタグです。
  4. 近いほど 1 に近づく Float を、HeadPat というパラメーターに入れます。

2. 頬染めのクリップを作る

  1. Project ウィンドウで右クリック → Create → Animation で、Blush というクリップを作ります。録画のしかたは第7回 アニメーションを作るを見てください。
  2. Animation ウィンドウでクリップを Blush にし、録画ボタンを押します。時間のバーを 0 にして、顔のメッシュの頬染めの BlendShape(例:cheek_blush)を 0 にします。
  3. 時間のバーを 1:00(1秒)に動かし、頬染めの BlendShape を 100 にします。録画を止めます。Motion Time では、クリップのはじめが 0、終わりが 1 に当たるので、HeadPat が 0.5 なら頬染めは 50 になります。
  4. 頬染めの BlendShape 以外は書きません。

3. FX にレイヤーを作る

  1. 自分の Animator Controller を Animator ウィンドウで開き、Parameters タブの + から Float を選んで、HeadPat と名前を付けます。Receiver に入れた名前と、大文字小文字まで同じにします。
  2. HeadPat は、Expression Parameters には足しません。Receiver が値を入れるので、メニューから動かす必要がないためです。
  3. Layers タブの + で HeadPat レイヤーを作り、歯車を押して Weight を 1 にします。
  4. Project ウィンドウから Blush のクリップを、Animator ウィンドウへドラッグします。ステートが1つできて、オレンジ色(デフォルト)になります。
  5. そのステートを選び、Inspector の Motion Time の横の Parameter にチェックを入れ、HeadPat を選びます。Write Defaults は、ほかのレイヤーとそろえます。トランジションは要りません。

Proximity でなく Constant にするときは、パラメーターを Bool にし、頬染め 0 のクリップと 100 のクリップのステートを2つ作って、HeadPat の true・false でトランジションさせます。Transition Duration を 0.3 くらいにすると、じわっと赤くなります。

4. つないで試す

  1. Animator Controller を MA Merge Animator で FX につなぎます(第8回 メニューでオンオフするギミックを作る)。HeadPat の GameObject はアバターの中にあるので、そのままアップロードに含まれます。
  2. Unity で再生し、Hierarchy に空の GameObject を作って VRC Contact Sender を足し、Collision Tags に Hand を入れます。Scene ビューでそれを頭に近づけ、Animator ウィンドウの Parameters で HeadPat の値が変わるかを見ます。
  3. Unity での試し方は、道具やバージョンで反応が違うことがあります。いちばん確かなのは、アップロードして、フレンドになでてもらうことです。Allow Self を一時的に入れて、自分の手で試すこともできます(試したら戻します)。

PhysBone のパラメーター(つかむと反応する)

髪やしっぽを揺らす VRC Phys Bone にも、Animator に値を渡すしくみがあります。PhysBone の Options にある Parameter に名前(例:Tail)を入れると、次のパラメーターが使えるようになります(VRChat の PhysBones のページ(新しいタブで開きます))。

パラメーター型中身
Tail_IsGrabbedBoolだれかにつかまれている間 true
Tail_IsPosedBoolつかんだあと、その形で止められている(ポーズ)間 true
Tail_AngleFloat0〜1。元の向きからどれだけ曲がったか。真反対(180°)で 1
Tail_StretchFloat0〜1。どれだけ伸びたか。いちばん伸びたとき(Max Stretch)で 1
Tail_SquishFloat0〜1。どれだけ縮んだか。いちばん縮んだとき(Max Squish)で 1

しっぽをつかむと驚いた顔になる

  1. Hierarchy でしっぽの PhysBone が付いた GameObject を選びます。Inspector の VRC Phys Bone の Options を開き、Parameter に Tail と入力します。
  2. 同じ PhysBone の Grab & Pose で、Allow Grabbing がつかめる設定になっているかを確かめます。つかめないと、IsGrabbed は true になりません。
  3. Animator の Parameters に、Bool で Tail_IsGrabbed を足します。
  4. Tail Face レイヤーを作り、Weight を 1 にします。ステートを2つ作り、Idle には表情を書かないクリップ(Face_None)、Grabbed には驚いた顔のクリップを入れます。Idle をデフォルトにします。
  5. Idle から Grabbed へのトランジションの条件を Tail_IsGrabbed が true、戻りを false にします。どちらも Has Exit Time を外し、Transition Duration は 0.1 くらいにします。
  6. Tail Face レイヤーを、ハンドサインの表情のレイヤーより下に置きます。同じ顔の BlendShape を書くレイヤーは、下のほうが勝つので、つかまれている間はハンドサインより驚いた顔が優先されます。

表情のクリップの作り方と、下のレイヤーで「表情を書かないクリップ」を使う理由は、第10回 ハンドサインで表情を変えるで解説しています。

つかむ・ポーズを付けるのを、自分だけ・ほかの人だけに許すこともできます。また、ほかの人の設定によっては、その人がつかめないことがあります。

ほかの人にも同じに見えるか

メニューで変えるパラメーターは、Expression Parameters で Synced にして、ほかの人に送ります。Contact や PhysBone のパラメーターは、これとしくみが違います。

VRChat の説明では、Receiver の Parameter は、Expression Parameters の同期の一覧に入れなくてよいとされています(VRChat の Contacts のページ(新しいタブで開きます))。PhysBone のパラメーターも同じで、自分の VRChat とほかの人の VRChat の両方で PhysBone が動き、それぞれで値が計算されます。Local Only でない Contact も、見ている人それぞれの VRChat で、あなたのアバターの Contact が調べられると考えてください。

そのため、ふつうは、ほかの人にもだいたい同じ反応が見えます。ただし、手の位置はネットワークで少し遅れて届くので、見る人によって、反応する瞬間や濃さが少しずれることがあります。OnEnter で回数を数えるような作りでは、人によって数が合わないこともあります。

パラメーターの出どころほかの人の画面Expression Parameters
Contact Receiver(Local Only なし)それぞれの VRChat で調べられ、だいたい同じに見える入れなくてよい
Contact Receiver(Local Only)動かない。反応は自分の画面だけ入れなくてよい
PhysBone の Parameterそれぞれの VRChat で計算され、だいたい同じに見える入れなくてよい
メニューで変えるパラメーター(比べるため)Synced なら送られて、同じに見える入れる

Local Only は、ほかの人に見せなくてよい反応(自分だけに聞こえる音など)に使います。頬染めのように見せたい反応には使いません。

同じ名前のパラメーターを Expression Parameters にも入れて同期すると、ほかの人の画面で、送られてきた値と、その人の VRChat が Contact で出した値のどちらが使われるかが分かりにくくなります。はじめは入れないでください。どうしても全員に同じ値を見せたいときは、Local Only の Receiver の値を、VRC Avatar Parameter Driver で同期するパラメーターに写す方法がありますが、上級者向けです。同期のしくみは第9回 段階で切り替える・少しずつ変えるギミックも見てください。

重さと数の上限

Contact の Sender と Receiver は、パフォーマンスランクの「Contacts」の項目で数えられます。PC では、8 個までなら Excellent、16 個までなら Good、24 個までなら Medium、32 個までなら Poor です(VRChat の Performance Ranks のページ、2026年10月21日更新による)。Local Only の Contact は数えられません。

Quest やスマホでは上限がずっと少なく、Very Poor の上限を超えると、アバターの Contact と PhysBone がすべて外されます。反応するギミックが、Quest やスマホの人には動かないことがあります。

ランクの決まり方と上限の表は第4回 パフォーマンスランクと軽量化、Quest・スマホでの扱いは第5回 Quest・スマホ対応で解説しています。

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

触っても何も起きない

起きること
ほかの人に頭をなでてもらっても、頬が赤くならない。
原因
Collision Tags の綴りや大文字小文字が違う(hand と Hand など)、Allow Others が外れている、Receiver の Parameter と Animator のパラメーターの名前か型が違う、レイヤーの Weight が 0、のどれかです。
直し方
上から順に確かめます。Unity で再生して、Animator の Parameters の値が変わるかを見ると、Receiver と Animator のどちらが悪いかが分かります。

自分の手でも反応してしまう

起きること
自分で髪を触ったり、頭の近くで手を動かしたりすると、頬が赤くなる。
原因
Receiver の Allow Self にチェックが入っています。
直し方
Allow Self を外します。ほかの人の手にだけ反応するようになります。

一瞬だけ反応してすぐ消える

起きること
触れた瞬間に何かが起きるが、触れ続けても続かない。
原因
Receiver Type が OnEnter です。OnEnter は、入った1フレームだけ値が入ります。
直し方
触れている間続けたいときは、Constant(Bool)か Proximity(Float)にします。

頬染めが付いたまま戻らない

起きること
手を離しても、頬が赤いまま残る。
原因
Write Defaults が OFF で、頬染めを 0 に戻すクリップが無いか、元のステートへ戻るトランジションがありません。
直し方
Constant なら、false で頬染め 0 のステートへ戻るトランジションを作ります。Proximity と Motion Time なら、クリップのはじめに頬染め 0 のキーを打ちます。

ほかの人には反応が見えない

起きること
自分の画面では頬が赤くなるのに、ほかの人には見えていないと言われる。
原因
Receiver の Local Only にチェックが入っています。または、見ている人が Quest やスマホで、Contact が外されています。
直し方
Local Only を外します。Quest やスマホの人には、ランクの上限を見直します。

しっぽをつかんでも変わらない

起きること
しっぽをつかまれても、表情が変わらない。
原因
PhysBone の Parameter が空か、Animator のパラメーター名が Tail_IsGrabbed と違います。または Allow Grabbing でつかめない設定です。表情のレイヤーより上にあり、上書きされていることもあります。
直し方
Parameter の名前と、Animator のパラメーター名(大文字小文字まで)を合わせます。Tail Face レイヤーを表情のレイヤーより下に置きます。

ギミックが動かないときの確かめ方は、第12回 ギミックが動かないときにまとめています。

気をつけること

  • Receiver は、反応させたい骨の子に置きます。アバターの直下に置くと、頭が動いても Receiver がついてきません。
  • Receiver を大きくしすぎると、近くを通っただけで反応します。Scene ビューで球の大きさを見ながら決めてください。
  • タグは、Sender と Receiver で1つでも同じものがあれば反応します。Hand と Finger を両方入れると、手のひらでも指先でも反応します。
  • Contact の数はランクに数えられます。同じ場所に Receiver をいくつも重ねず、1つの Receiver の値を、いくつものレイヤーで使い回します。
  • 反応させたい表情が、ハンドサインの表情とぶつかるときは、どちらを優先するかをレイヤーの並びで決めます。

まとめ

  • Contact は、Sender が Receiver に入ると、Receiver が Animator のパラメーターに値を入れるしくみです。
  • 触れている間は Constant、触れた瞬間は OnEnter、近さで変えたいときは Proximity を使います。
  • Collision Tags は両方に同じものが要り、大文字小文字まで合わせます。Allow Self・Allow Others で、だれに反応するかを決めます。
  • PhysBone の Parameter に名前を入れると、_IsGrabbed などでつかまれたことが分かります。
  • Contact と PhysBone のパラメーターは同期しなくても、ふつうはほかの人にもだいたい同じに見えます。Local Only は自分の画面だけです。

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