ワールドにコップやペンを置いて、手に取れるようにしたい。持ったまま歩いて、机に置き直せるようにしたい。
VRChatにはこれ専用の部品があります。ただ、そのまま付けると 床に沈んだり、放した瞬間に飛んでいったり します。組み合わせに条件があるからです。
この記事では、持てる懐中電灯を作り、Useボタンで点灯させる ところまでを解説します。
この記事でわかること
- Pickupに必要な3つの部品
- 掴む・使う・離すのイベント
- 飛んでいく、沈むといった問題への対処
- 握り位置を整える方法
変数と参照 を試した状態から始めます。
Pickupは3つの部品でできている
持てる物を作るには、3つがそろっている必要があります。

| 部品 | 役割 |
|---|---|
| Collider | 掴む判定と、物にぶつかる形 |
| Rigidbody | 手を離したときに落ちる、転がる |
| VRC Pickup | 掴めるようにする |
この3つは、同じGameObjectに付ける必要があります。 子オブジェクトにColliderがある構成では動きません。ここが最初のつまずきです。
VRC Pickup を追加すると、Rigidbodyが自動で付くことがあります。それでも、Colliderが同じ階層にあるかは自分で確認してください。
主な設定は3つ覚えれば足ります。
| 設定 | 意味 |
|---|---|
Pickupable | いま掴めるかどうか。オフにすると掴めなくなる |
Auto Hold | 掴んだあと手に持ち続けるか |
Proximity | 掴める距離 |
Auto Hold は動きが変わるので、試して確かめる価値があります。オンなら「掴んだら持ちっぱなし」、オフなら「ボタンを押しているあいだだけ持つ」になります。懐中電灯のように使いながら持つ物は、オンが向いています。
実践:持てる懐中電灯を作る
持てる小物を作って、持ったままUseボタンで光を点けます。

1. 懐中電灯を組み立てる
「Create Empty」で Flashlight を作り、(0, 1, 1) に置きます。TransformのRotationとScaleは初期値のままです。
その子に、次の3つを作ります。
| 子の名前 | 作るもの | Local Position | Local Scale |
|---|---|---|---|
Body | Cube | (0, 0, 0) | (0.08, 0.08, 0.25) |
Lens | Cube | (0, 0, 0.14) | (0.06, 0.06, 0.03) |
Beam | Spot Light | (0, 0, 0.16) | (1, 1, 1) |
Beam のSpot Lightは、Rangeを 10、Spot Angleを 35、Intensityを 3、ModeをRealtimeにします。Rotationは (0, 0, 0) のままで、Z軸の方向(懐中電灯の前)を照らします。
作ったら、Beam を 無効にしておきます。消えた状態から始めます。
2. 掴めるようにする
親の Flashlight を選んで、次を追加します。
- 「Add Component」で Box Collider を追加する。Sizeを
(0.1, 0.1, 0.3)くらいにして、本体を包む大きさにする - 「Add Component」で VRC Pickup を追加する(Rigidbodyも一緒に付きます)
VRC Pickupの設定は、まずこうします。
| 項目 | 設定 |
|---|---|
| Pickupable | オン |
| Auto Hold | オン |
| Orientation | Any(あとで調整します) |
| Use Text | 点ける |
Rigidbodyは、Use Gravityをオンのまま、Is Kinematicはオフのままです。手を離したら落ちる、という自然な動きになります。
ここで一度Playしてみてください。掴んで持ち運べれば、ここまでは成功です。
3. Useで点灯するコードを書く
Assets/Scripts で「Create → U# Script」を選び、FlashlightToggle を作ります。
using UdonSharp;
using UnityEngine;
[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class FlashlightToggle : UdonSharpBehaviour
{
[SerializeField] private Light beam;
private bool isOn;
private void Start()
{
Apply();
}
// 持っているあいだにUseを押したとき
public override void OnPickupUseDown()
{
isOn = !isOn;
Apply();
Debug.Log("[Flashlight] on=" + isOn);
}
// 手を離したときは、消しておく
public override void OnDrop()
{
isOn = false;
Apply();
}
private void Apply()
{
if (beam != null) beam.enabled = isOn;
}
}
OnPickupUseDown() は、持っているあいだにUseボタンを押したとき に呼ばれます。持っていないときは呼ばれません。
OnDrop() で消しているのは、床に落ちた懐中電灯が点きっぱなしにならないようにするためです。細かい配慮ですが、こういう後始末があると自然に見えます。
主なイベントはこの4つです。
| イベント | 呼ばれるとき |
|---|---|
OnPickup() | 掴んだ瞬間 |
OnDrop() | 手を離した瞬間 |
OnPickupUseDown() | 持っているあいだにUseを押した |
OnPickupUseUp() | そのUseを離した |
どれも、操作した本人のPCでしか呼ばれません。
4. 割り当てて確かめる
Flashlight に Udon Behaviour を追加し、FlashlightToggle を指定します。Beamに子の Beam をドラッ グします。
Playして試してください。
| 操作 | 期待する結果 |
|---|---|
| 懐中電灯に近づいて掴む | 手に持てる |
| 持ったままUse(左クリック) | 光が点く。Consoleに on=True |
| もう一度Use | 消える |
| 手を離す | 床に落ちて、光も消える |
暗い部屋で試すと分かりやすくなります。Directional Lightを一時的に弱めてみてください。
握り位置を整える
持ってみると、向きが変だったり、手からずれていたりすることがあります。

VRC Pickupの Orientation で、持ち方の基準を選べます。
| 設定 | 持ち方 |
|---|---|
Any | 掴んだ位置と向きのまま持つ |
Gun | 銃のように、決まった向きで持つ |
Grip | 握るように、決まった向きで持つ |
Any は自然ですが、掴む場所によって向きが変わります。懐中電灯のように「必ずこの向きで持ってほしい」物は、Gun か Grip を使います。
Gun を選ぶと、Exact Gun という欄が出ます。ここに空のオブジェクトを指定すると、その位置と向きで持つようになります。
Flashlightの子に「Create Empty」でGripPointを作る- 懐中電灯の持ち手のあたり、
(0, 0, -0.08)くらいに置く - VRC Pickupの Orientation を
Gunにして、Exact Gun にGripPointを指定する
Playして持ち直すと、必ず同じ向きで持てるようになります。
ただし、最初から凝らなくて構いません。 Any のままでも十分使えます。持ってみて気になったら調整する、くらいの順番で足ります。
うまくいかないときは
- 掴めない → ColliderとRigidbodyが、VRC Pickupと同じGameObjectにあるかを確認します。子に付いていると動きません
- 床に沈む → Colliderが小さすぎるか、位置がずれています。Sceneビューで緑の枠が本体を包んでいるか見ます
- 離すと飛んでいく → 手を振りながら離すと、その勢いが乗ります。仕様です。気になる場合は Rigidbody の Drag を上げると落ち着きます
- Useを押しても反応しない →
OnPickupUseDown()は持っているあいだだけ呼ばれます。掴んでいるか確認します - 他の人の画面で動かない → 位置は共有されていません。次の項目を参照してく ださい
おまけ:先に知っておくと良いこと
- 位置の共有には別の部品が要る: 持ち運びを全員に見せるには VRC Object Sync を追加します。ただし点灯のような状態は、また別に同期する必要があります。VRC Object Sync で扱います
- Pickupはプレイヤーと衝突しない: レイヤーの設定でそうなっています。持った物が自分にぶつかって邪魔にならないための配慮です
- 数を増やしすぎない: Rigidbodyの物が多いほど物理の計算が増えます。転がる小物は数個までにしておくと安心です
- Interactと一緒に付けない: 同じオブジェクトにInteractの処理を付けると、掴む操作が優先されて反応しなくなります
- 使いどころはいろいろ: カフェのコップ、脱出ゲームの鍵、ボードゲームの駒、展示ワールドの手に取れる資料。どれも同じ形で作れます
まとめ
持てる物は、3つの部品がそろって初めて動きます。
- Collider・Rigidbody・VRC Pickupを、同じGameObjectに 付ける
Auto Holdをオンにすると、掴んだら持ちっぱなしになるOnPickupUseDown()は、持っているあいだのUseだけを受け取る- 握り位置が気になったら、Orientationと空のオブジェクトで調整する
作ったあとの問いかけは、「掴んで、使って、置き直せるか」 です。この3つが自然に回れば合格です。
持ち運びを全員に見せたいなら VRC Object Sync へ、鏡を置いて見た目を確かめる なら ミラーを置く へ進んでください。