触ると反応するギミック
頭をなでられると頬が赤くなる。しっぽをつかまれると驚いた顔になる。触れたことを 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 | パラメーターの型 | 入る値 | 向いている使い方 |
|---|---|---|---|
| Constant | Bool(Float・Int も可) | 触れている間ずっと true(1)。離れると false(0) | 触れている間だけ表情を変える、頬を赤くする |
| OnEnter | Bool(Float・Int も可) | 触れた瞬間の1フレームだけ true(1)。次のフレームで戻る | 触れたら1回だけ何かを始める(音を鳴らす、アニメーションを1回流す) |
| Proximity | Float だけ | 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
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 を置く
- Hierarchy でアバターの中を開き、Armature の中の頭の骨(Head)を探します。名前や並びはアバターで違います(例:
Armature → Hips → Spine → Chest → Neck → Head)。 - Head を右クリックし、
Create Emptyを押します。できた GameObject の名前をHeadPatにします。頭の骨の子にするのは、頭が動いても Receiver がついてくるようにするためです。 HeadPatを選んだまま、Inspector の下のAdd Componentを押し、VRC Contact Receiverと入力して足します。Shape TypeをSphereにし、Radiusを 0.1〜0.15 くらいにします。Scene ビューに球の線が出ます。Positionの Y を少し上げて、球が頭のてっぺんにかぶるようにします。値はアバターの大きさで変わるので、Scene ビューで見ながら決めます。Allow Othersにチェックを入れます。自分の手でなでても反応させたいときは、Allow Selfにもチェックを入れます。Local Onlyは外したままにします(理由は下の「ほかの人にも同じに見えるか」で説明します)。Collision TagsのAddを押し、出てくる一覧からHandを選びます。もう一度押してFingerも足します。手で入力するときは、大文字と小文字まで同じにします。Receiver TypeをProximityにし、ParameterにHeadPatと入力します。
Shape
Filtering
Receiver
- 頭のてっぺんを包む大きさの球にします。
- ほかの人の手に反応させます。自分の手でも反応させるなら Allow Self も入れます。
- VRChat が手と指に自動で付けている Sender のタグです。
- 近いほど 1 に近づく Float を、HeadPat というパラメーターに入れます。
2. 頬染めのクリップを作る
- Project ウィンドウで右クリック →
Create → Animationで、Blushというクリップを作ります。録画のしかたは第7回 アニメーションを作るを見てください。 - Animation ウィンドウでクリップを
Blushにし、録画ボタンを押します。時間のバーを 0 にして、顔のメッシュの頬染めの BlendShape(例:cheek_blush)を 0 にします。 - 時間のバーを 1:00(1秒)に動かし、頬染めの BlendShape を 100 にします。録画を止めます。Motion Time では、クリップのはじめが 0、終わりが 1 に当たるので、HeadPat が 0.5 なら頬染めは 50 になります。
- 頬染めの BlendShape 以外は書きません。
3. FX にレイヤーを作る
- 自分の Animator Controller を Animator ウィンドウで開き、
Parametersタブの+からFloatを選んで、HeadPatと名前を付けます。Receiver に入れた名前と、大文字小文字まで同じにします。 HeadPatは、Expression Parameters には足しません。Receiver が値を入れるので、メニューから動かす必要がないためです。Layersタブの+でHeadPatレイヤーを作り、歯車を押してWeightを 1 にします。- Project ウィンドウから
Blushのクリップを、Animator ウィンドウへドラッグします。ステートが1つできて、オレンジ色(デフォルト)になります。 - そのステートを選び、Inspector の
Motion Timeの横のParameterにチェックを入れ、HeadPatを選びます。Write Defaultsは、ほかのレイヤーとそろえます。トランジションは要りません。
Proximity でなく Constant にするときは、パラメーターを Bool にし、頬染め 0 のクリップと 100 のクリップのステートを2つ作って、HeadPat の true・false でトランジションさせます。Transition Duration を 0.3 くらいにすると、じわっと赤くなります。
4. つないで試す
- Animator Controller を MA Merge Animator で FX につなぎます(第8回 メニューでオンオフするギミックを作る)。
HeadPatの GameObject はアバターの中にあるので、そのままアップロードに含まれます。 - Unity で再生し、Hierarchy に空の GameObject を作って
VRC Contact Senderを足し、Collision TagsにHandを入れます。Scene ビューでそれを頭に近づけ、Animator ウィンドウの Parameters でHeadPatの値が変わるかを見ます。 - Unity での試し方は、道具やバージョンで反応が違うことがあります。いちばん確かなのは、アップロードして、フレンドになでてもらうことです。Allow Self を一時的に入れて、自分の手で試すこともできます(試したら戻します)。
PhysBone のパラメーター(つかむと反応する)
髪やしっぽを揺らす VRC Phys Bone にも、Animator に値を渡すしくみがあります。PhysBone の Options にある Parameter に名前(例:Tail)を入れると、次のパラメーターが使えるようになります(VRChat の PhysBones のページ(新しいタブで開きます))。
| パラメーター | 型 | 中身 |
|---|---|---|
| Tail_IsGrabbed | Bool | だれかにつかまれている間 true |
| Tail_IsPosed | Bool | つかんだあと、その形で止められている(ポーズ)間 true |
| Tail_Angle | Float | 0〜1。元の向きからどれだけ曲がったか。真反対(180°)で 1 |
| Tail_Stretch | Float | 0〜1。どれだけ伸びたか。いちばん伸びたとき(Max Stretch)で 1 |
| Tail_Squish | Float | 0〜1。どれだけ縮んだか。いちばん縮んだとき(Max Squish)で 1 |
しっぽをつかむと驚いた顔になる
- Hierarchy でしっぽの PhysBone が付いた GameObject を選びます。Inspector の
VRC Phys BoneのOptionsを開き、ParameterにTailと入力します。 - 同じ PhysBone の
Grab & Poseで、Allow Grabbingがつかめる設定になっているかを確かめます。つかめないと、IsGrabbed は true になりません。 - Animator の
Parametersに、BoolでTail_IsGrabbedを足します。 Tail Faceレイヤーを作り、Weight を 1 にします。ステートを2つ作り、Idleには表情を書かないクリップ(Face_None)、Grabbedには驚いた顔のクリップを入れます。Idleをデフォルトにします。IdleからGrabbedへのトランジションの条件をTail_IsGrabbedがtrue、戻りをfalseにします。どちらも Has Exit Time を外し、Transition Duration は 0.1 くらいにします。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 は自分の画面だけです。