ワー ルドに何人いるか、壁に表示したい。誰かが入ってきたら歓迎の音を鳴らしたい。
VRChatには、参加と退出を受け取るイベントがあります。ただし「誰のクライアントで、誰について呼ばれるのか」が分かっていないと、人数が合わなくなります。
この記事では、参加と退出を受け取って、壁の掲示板に「いま3人」と表示する ところまでを作ります。
この記事でわかること
- 誰のクライアントで、誰について呼ばれるか
- 入室時に、先にいた人の分も呼ばれること
- 人数の正しい数え方
- UdonからTextMeshProに文字を出す方法
変数と参照 を試した状態から始めます。
誰のPCで、誰について呼ばれるか
プレイヤーイベントは、この2つを分けて考えると混乱しません。

OnPlayerJoined(VRCPlayerApi player) は、インスタンスにいる全員のPCで 呼ばれます。引数の player が「入ってきた人」です。
- Aさんが入る → その場にいるBさん・Cさんのクライアントで
OnPlayerJoined(A)が呼ばれる - 同時に、Aさん自身のクライアントでも
OnPlayerJoined(A)が呼ばれる
ここまではイメージどおりだと思います。大事なのは次です。
自分が入ったとき、既にいた人の分も呼ばれます。
Aさんが入った時点でBさんとCさんがいたなら、Aさんのクライアントでは OnPlayerJoined(A) OnPlayerJoined(B) OnPlayerJoined(C) が順に実行されます。その場にいる全員分 です。
この仕組みのおかげで、あとから入った人でも「いま誰がいるか」を自分で把握できます。もしこれがなければ、入室後に来た人しか分からず、人数がずれます。
退出も同じです。OnPlayerLeft(VRCPlayerApi player) が、残っている全員のPCで呼ばれます。
同期は使っていません。 各自のPCが、自分で数えて自分の画面を書き換えます。それでも全員が同じ数になります。
実践:人数を掲示板に表示する
壁の掲示板に、いまワールドにいる人数を表示します。誰かが出入りするたびに更新されます。

1. 掲示板を作る
文字を表示するには、World Space の Canvas が必要です。ワールドの中に浮かぶ看板だと思ってください。
- Hierarchyで「UI → Canvas」を作り、
InfoCanvasと名付ける - CanvasのRender Modeを World Space にする
- Rect Transformを Position
(0, 2, 2.8)、Width400、Height200、Scale を(0.005, 0.005, 0.005)にする InfoCanvasを右クリックして「UI → Text - TextMeshPro」を追加し、CountTextと名付ける
Canvasの Scale を小さくしているのは、UIの1単位がそのままメートルになってしまうためです。0.005にすると、幅400のCanvasが2mの看板になります。
CountText の Font Size を 72 くらいにして、Alignment を中央にします。
2. コードを書く
Assets/Scripts で「Create → U# Script」を選び、PlayerCounter を作ります。
using UdonSharp;
using UnityEngine;
using TMPro;
using VRC.SDKBase;
[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class PlayerCounter : UdonSharpBehaviour
{
[SerializeField] private TextMeshProUGUI countText;
private void Start()
{
UpdateDisplay();
}
// 誰かが入ってきたとき(自分が入ったときも呼ばれる)
public override void OnPlayerJoined(VRCPlayerApi player)
{
UpdateDisplay();
Debug.Log("[PlayerCounter] 参加:" + player.displayName);
}
// 誰かが出ていったとき
public override void OnPlayerLeft(VRCPlayerApi player)
{
UpdateDisplay();
Debug.Log("[PlayerCounter] 退出:" + player.displayName);
}
// 人数を数え直して、表示に反映する
private void UpdateDisplay()
{
if (countText == null) return;
int count = VRCPlayerApi.GetPlayerCount();
countText.text = "いま " + count + " 人";
}
}
短いです。ポイントは UpdateDisplay() の中身にあります。
変数で人数を足し引きしていません。 イベントが来るたびに GetPlayerCount() で数え直しています。この理由は次の節で説明します。
3. 割り当てて確かめる
InfoCanvas に Udon Behaviour を追加し、PlayerCounter を指定します。Count Text に CountText をドラッグします。
ClientSimでPlayすると、「いま 1 人」と出ます。自分1人だからです。
本番の確認はBuild & Testで行います。 Number of Clients を 2 にしてビルドしてください。
| 操作 | 期待する結果 |
|---|---|
| 1人目が入る | 「いま 1 人」 |
| 2人目が入る | 両方の画面で「いま 2 人」 |
| 2人目が出る | 残った画面で「いま 1 人」 |
両方の画面で同じ数字が出ること を確かめてください。同期のコードは1行も書いていないのに、そろっています。各自が自分で数えているからです。
数えるのではなく、取り直す
人数の数え方には2つの流儀があります。

イベントで足し引きする方法 はこうです。
private int count;
public override void OnPlayerJoined(VRCPlayerApi player)
{
count++; // 増やす
}
public override void OnPlayerLeft(VRCPlayerApi player)
{
count--; // 減らす
}
一見よさそうですが、一度ずれると戻りません。 何かの理由でイベントを取りこぼしたり、初期値がずれたりすると、実際の人数と食い違ったまま動き続けます。
毎回取り直す方法 なら、その心配がありません。
int count = VRCPlayerApi.GetPlayerCount();
GetPlayerCount() は、呼んだ時点の実際の人数を返します。イベントは「いま人数が変わった」というきっかけとして使い、数そのものは毎回聞き直す。これが安全な作り方です。
同じ考え方は、他の場面でも効きます。「自分で数えて覚えておく」より、「必要なときに実際の値を取る」ほうが、ずれる余地がありません。
うまくいかないときは
- 文字が表示されない → Count Textが
Noneになっていないか。CanvasのRender ModeがWorld Spaceか - 看板が巨大/極小 → CanvasのScaleが
1のままかもしれません。0.005前後にします - ClientSimで人数が増えない → ClientSimでは他のプレイヤーが本物ではありません。Build & Testで2人にして確かめます
- 人数が実際と合わない → 変数で足し引きしていませんか。
GetPlayerCount()で取り直します
おまけ:先に知っておくと良いこと
isLocalで自分だけ処理できる:player.isLocalがtrueなら、そのイベントは自分についてのものです。「自分が入ったときだけ案内を出す」といった処理に使いますdisplayNameで名前が取れる: ログや歓迎メッセージに使えます。ただし表示する場合は、長い名前や特殊な文字も来ることを想定しておきます- 全員のリストも取れる:
VRCPlayerApi.GetPlayers()で配列として取得できます。ただし呼ぶたびに配列を作るので、毎フレーム呼ぶのは避けます - 入った直後は準備が整っていないことがある: 参加した瞬間にそのプレイヤーの位置を読もうとすると、まだ確定していない場合があります。少し待ってから読むほうが安全です(時間差で処理を呼ぶ)
Utilities.IsValid()で確認する: プレイヤーが既に退出している場合があるので、保存しておいた参照を使う前に確認します
まとめ
プレイヤーイベントは、2つの軸で考えます。
- 誰のPCで呼ばれるか → その場にいる全員のPC
- 誰について呼ばれるか → 引数の
player - 自分が入ったときは、既にいた人の分も全部呼ばれる
- 人数は変数で数えず、
GetPlayerCount()で取り直す
作るときの問いかけは、「この値は自分で覚えておくべきか、それとも聞き直せるか」 です。聞き直せるなら、そのほうがずれません。
次は、複数のオブジェクトをまとめて扱います。配列入門 で、3灯のライトを順番に切り替えてみましょう。