【VRChat】ワールド内UIを作る:ボタンとスライダーでUdonを呼ぶ

作成: 2026-09-08最終更新: 2026-09-09

World Space Canvasにボタンとスライダーを置き、押すとUdonの処理が動く設定パネルを作ります。VRChatで押せるようにするために必要な部品と、反応しないときの原因を解説します。

BGMの音量を訪問者が調整できるようにしたい。照明の明るさを好みで変えられるようにしたい。

こういう設定パネルを作るには、ワールドの中に浮かぶUIが必要です。ただ、Unityの手順どおりに作ると、エディタでは押せるのにVRChatでは反応しない ことがよくあります。

この記事では、VRChatで確実に押せるパネル を作り、ボタンとスライダーからUdonの処理を呼ぶところまでを解説します。

空中に浮かぶパネルを、レーザーポインタで操作している

この記事でわかること

  • VRChatでUIを押せるようにする4つの部品
  • ボタンからUdonのメソッドを呼ぶ手順
  • スライダーの値を受け取る方法
  • 押せないときの原因を頻度順に

メソッドとカスタムイベント を試した状態から始めます。

Sponsored


押せるようにするには4つの部品が要る

Unityで作ったUIは、エディタのPlayではマウスで押せます。ところがVRChatに上げると押せません。

VRChatのレーザーポインタを、UnityのUIにつなぐ部品が足りない からです。

Canvas・Graphic Raycaster・VRC Ui Shape・EventSystemの4つがそろって初めて押せる

必要なのはこの4つです。

部品役割どこに付けるか
Canvas(World Space)UIを置く板自分で作る
Graphic Raycasterポインタが当たったかを判定するCanvasと同じ(自動で付く)
VRC Ui ShapeVRChatの指し棒をUnityのUIにつなぐCanvasと同じ(自分で追加)
EventSystemクリックを配る受け皿シーンに1つだけ

いちばん多い失敗が、VRC Ui Shape の付け忘れ です。これがないと、エディタでは押せてVRChatでは押せない、という分かりにくい状態になります。

追加すると Box Collider が自動で付きます。この Collider が「触れる面」になるので、自分でColliderを足す必要はありません。

もう1つ、レイヤーは Default のままにします。 UI レイヤーにしてはいけません。VRChatクライアント自身のメニューが UI レイヤーを使っているので、そこに置くとワールドのポインタが当たらなくなります。

EventSystemはシーンに1つだけ です。UIを最初に作ったときに自動で追加されます。複数あると動かなくなるので、増えていないか確認してください。

Sponsored

実践:音量と照明の設定パネルを作る

BGMの音量をスライダーで、照明のオン・オフをボタンで操作できるパネルを作ります。

1. パネルを置く

「UI → Canvas」を作り、ControlPanel と名付けます。

項目設定
Render ModeWorld Space
Position(0, 1.4, 2.8)
Rotation(0, 180, 0)
Width / Height400 / 300
Scale(0.005, 0.005, 0.005)
LayerDefault
World Spaceでは1単位が1メートルになるので、Scaleで調整する

Scaleを小さくしているのは、World SpaceのCanvasでは1単位が1メートルとして扱われる からです。Widthが400のままだと400mの板になります。0.005倍にすると、幅2m・高さ1.5mの現実的な大きさになります。

「Add Component」で VRC Ui Shape を追加します。これで押せるようになります。

Hierarchyに EventSystem があることも確認してください。なければ、UI要素を作ったときに自動で追加されます。

2. スライダーとボタンを置く

ControlPanel を右クリックして、次を追加します。

  • 「UI → Slider」を追加して VolumeSlider と名付け、パネルの上半分に配置する
  • 「UI → Button - TextMeshPro」を追加して LightButton と名付け、下半分に配置する

Sliderの Min Value を 0、Max Value を 1、Value を 0.12 にします。BGMの音量として使うためです。

ボタンのテキストは「照明を切り替える」にしておきます。

3. 操作を受け取るコードを書く

「Create Empty」で PanelController を作り、(0, 0, 0) に置きます。

Assets/Scripts で「Create → U# Script」を選び、RoomControlPanel を作ります。

using UdonSharp;
using UnityEngine;
using UnityEngine.UI;

[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class RoomControlPanel : UdonSharpBehaviour
{
    [SerializeField] private AudioSource bgm;
    [SerializeField] private Light roomLight;
    [SerializeField] private Slider volumeSlider;

    private bool lightOn = true;

    private void Start()
    {
        ApplyVolume();
        ApplyLight();
    }

    // スライダーから呼ばれる。引数は取れないので、値は自分で読む
    public void OnVolumeChanged()
    {
        ApplyVolume();
    }

    // ボタンから呼ばれる
    public void ToggleLight()
    {
        lightOn = !lightOn;
        ApplyLight();
        Debug.Log("[ControlPanel] light=" + lightOn);
    }

    private void ApplyVolume()
    {
        if (bgm == null || volumeSlider == null) return;
        bgm.volume = volumeSlider.value;
    }

    private void ApplyLight()
    {
        if (roomLight != null) roomLight.enabled = lightOn;
    }
}

大事なのは、UIから呼ばれるメソッドが public で引数を取らない ことです。

スライダーの値は引数では渡ってきません。呼ばれた側が volumeSlider.value自分で読みに行きます。 そのためにスライダーへの参照を持っています。

4. UIとUdonをつなぐ

PanelController に Udon Behaviour を追加し、RoomControlPanel を指定します。BGM・Room Light・Volume Sliderをそれぞれ割り当てます。

次に、UI側から呼ぶ設定をします。

ボタンやスライダーの操作が、Udonのメソッドを呼ぶ流れ

ボタンの場合:

  1. LightButton を選び、Inspectorの On Click ()+ を押す
  2. 空いた欄に、Hierarchyの PanelController をドラッグする
  3. 右のドロップダウンから UdonBehaviour → SendCustomEvent を選ぶ
  4. 下のテキスト欄に ToggleLight と入力する

スライダーの場合:

  1. VolumeSlider を選び、On Value Changed (Single)+ を押す
  2. PanelController をドラッグする
  3. UdonBehaviour → SendCustomEvent を選ぶ
  4. テキスト欄に OnVolumeChanged と入力する

メソッド名は文字で入力するので、つづりを間違えると何も起きません。 コードのメソッド名と1文字ずつ照らし合わせてください。

5. 確かめる

Playして、パネルを操作します。

操作期待する結果
ボタンを押す照明が消える。Consoleに light=False
もう一度押す点く
スライダーを動かすBGMの音量が変わる
パネルから離れて操作する離れすぎると届かない

ClientSimで押せても油断しないでください。 VRC Ui Shapeの付け忘れは、実際のVRChatで初めて分かります。Build & Testでも確認します。

押せないときの原因

頻度の高い順に並べます。

押せないときに疑う3つ
  1. VRC Ui Shape が付いていない → Canvasと同じオブジェクトに追加します。エディタで押せてVRChatで押せない場合は、まずここです
  2. レイヤーが UI になっているDefault に戻します
  3. EventSystemがない、または複数ある → シーンに1つだけにします
  4. Graphic Raycaster が消えている → Canvasと同じオブジェクトにあるか確認します
  5. メソッド名のつづりが違う → SendCustomEventに入れた文字とコードを照合します
  6. Canvasのスケールが極端 → 巨大すぎると当たり判定がずれます。0.005前後にします

Canvasの大きさを後から変えた場合、VRC Ui Shapeが付けたColliderが古いサイズのまま残ることがあります。そのときは、一度外して付け直します。

Sponsored

おまけ:先に知っておくと良いこと

  • VRとデスクトップで操作が違う: VRはコントローラのレーザー、デスクトップは画面中央のポインタです。どちらでも押せる大きさにしておきます。ボタンは小さくしすぎないほうが親切です
  • これはローカルの処理です: 音量も照明も、操作した人の画面だけが変わります。音量は各自で決められるほうが親切なので、これで正解です。全員に共有したいものは ネットワーク同期入門
  • 設定を次回も覚えさせられる: 音量の設定を、次に来たときも保つことができます。PlayerDataで音量を保存する で扱います
  • パネルの高さに注意: 座って遊ぶ人は目線が1.1m前後まで下がります。パネルを高く置きすぎると、座ったまま操作できません
  • 使いどころはいろいろ: 交流ワールドの音量調整、ゲームの難易度選択、展示ワールドの言語切り替え、イベント会場の照明操作。どれも同じ形で作れます

まとめ

ワールド内UIは、4つの部品がそろって初めて動きます。

  • Canvas・Graphic Raycaster・VRC Ui Shape・EventSystem
  • レイヤーは DefaultUI にしない
  • World Spaceでは1単位が1メートル。Scaleで調整する
  • ボタンからは SendCustomEvent でメソッド名を呼ぶ。引数は渡せない

作ったあとの問いかけは、「VRChatでも押せたか」 です。エディタで押せることは、その証明になりません。

設定を次回も覚えさせるなら PlayerDataで音量を保存する、端末ごとの使いやすさを整えるなら 使いやすい設定パネル へ進んでください。

VRChat このセクションのノート63