概要
ワールド内でプレイヤーが椅子に座ってくつろいだり、乗り物に乗って移動したりする機能は、プレイヤーに役割を与え、没入感を飛躍的に向上させます。VRChatでは、このような「プレイヤーを特定の位置・姿勢で拘束する」機能をステーション (VRCStation) を使って実現します。
UdonSharpとVRCStationを組み合わせることで、単純な椅子から、動く乗り物の座席、あるいは特殊なアニメーションを再生する拘束具まで、様々なギミックを作成できます。
本記事では、VRCStationコンポーネントの基本的な使い方と、UdonSharpと連携させたインタラクティブな座席システムの実装方法を解説します。
ステップ1: VRCStationコンポーネントの設定
まず、プレイヤーに座ってほしいオブジェクト(例: 椅子のモデル)に、ステーションとしての機能を追加します。
-
オブジェクトの準備: シーンに椅子やベッドなどの3Dモデルを配置します。
-
VRCStationの追加: 椅子オブジェクトにVRCStationコンポーネントを追加します。これだけで、基本的な「座る」機能は有効になります。 -
Udon Behaviourの追加: 同じオブジェクトにUdon Behaviourコンポーネントを追加し、スクリプト連携の準備をします。
VRCStationの主要な設定項目
InteractionText: ステーションに照準を合わせたときに表示されるテキスト(例: 「座る」)。Player Mobility: ステーション使用中のプレイヤーの移動制限を設定します。Mobile: 移動可能。乗り物などに使用。Immobilize: 移動不可。椅子やベッドなど、その場に固定する場合に使用。
Can Use Station From Station: 他のステーションを使用中に、このステーションを使用できるか。チェ ックを外すと、椅子を乗り継ぐようなことができなくなります。Disable Station Exit:trueにすると、プレイヤーは自力で(移動キーで)ステーションから出られなくなります。UdonからExitStation()を呼ばないと出られないようにする場合に使います。Station Enter Player Location: プレイヤーがステーションを使用する際に移動する位置と向きを指定するTransform。指定しない場合、ステーションオブジェクト自身の位置になります。アバターの基点(足元)がこの位置に来ます。Station Exit Player Location: プレイヤーがステーションから出る際に移動する位置を指定するTransform。通常はステーションの前方などを指定します。Seated:trueにすると、着席アニメーション(座る、寝るなど)をアバターに適用しようと試みます。trueにすると、Player Mobilityは自動的にImmobilizeになります。
位置調整のコツ
Station Enter Player Locationには、空のGameObjectを別途作成して割り当てるのがおすすめです。この空オブジェクトを「EnterPoint」などと名付け、椅子オブジェクトの子にします。- 「EnterPoint」の位置を調整して、アバターが座ったときに自然に見える位置を探します。アバターの足元がこのポイントに来ることを意識してください。向き(青いZ軸)がプレイヤーの正面になります。
ステーション関連のUdonSharpイベント
VRCStationがアタッチされたオブジェクトでは、プレイヤーがステーションを使用・退出する際に、以下のUdonSharpイベントが呼び出されます。
OnStationEntered(VRCPlayerApi player): プレイヤーがステーションの使用を開始した時に呼び出されます。引数playerは、ステーションに入ったプレイヤーです。OnStationExited(VRCPlayerApi player): プレイヤーがステーションの使用を終了した時に呼び出されます。
これらのイベントは、ステーションに入ったプレイヤーのクライアントだけでなく、インスタンス内の全プレイヤーのクライアントで実行されます。これにより、誰かが椅子に座ったことを全プレイヤーが知ることができます。
実装例: 使用状況が同期される椅子
誰かが座っている間は、他の人が座れないように制御された椅子を実装します。これは、ステーションギミックの最も基本的な同期パターンです。
スクリプト: SyncedChair.cs
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
public class SyncedChair : UdonSharpBehaviour
{
private VRCStation station;
// UdonSharpのStartは、UnityのAwakeのタイミングで呼ばれる
void Start()
{
// 同じGameObjectにアタッチされているVRCStationコンポーネントを取得
station = GetComponent<VRCStation>();
}
// 誰かがステーションに入った時に全プレイヤーで呼ばれる
public override void OnStationEntered(VRCPlayerApi player)
{
// 誰かが入ったら、他の人はもう使えないようにする
// DisableInteractiveはローカルでのみ設定すればOK
this.DisableInteractive = true;
}
// 誰かがステーションから出た時に全プレイヤーで呼ばれる
public override void OnStationExited(VRCPlayerApi player)
{
// 誰も使っていなければ、再度使えるようにする
this.DisableInteractive = false;
}
}
Unityでの設定
- 椅子オブジェクトに
VRCStationとUdon Behaviourを追加します。 VRCStationのInteractionTextを「座る」に、Seatedをtrueに設定します。SyncedChair.csスクリプトを作成し、Udon Behaviourに割り当てます。
これだけで、誰かが椅子に座っている間は、他のプレイヤーがその椅子にインタラクトできなくなります。DisableInteractiveは各クライアントで個別に設定すればよいため、このケースでは[UdonSynced]変数を使った複雑な同期は不要です。
応用: Udonからステーションを制御する
Interactで座るだけでなく、UdonSharpから特定のプレイヤーを強制的にステーションに座らせることもできます。
// stationはVRCStationコンポーネントへの参照
// playerは座らせたいプレイヤーのVRCPlayerApi
// プレイヤーをステーションに座らせる
station.UseStation(player);
// プレイヤーをステーションから立たせる
station.ExitStation(player);
注意:
UseStation(player)とExitStation(player)は、ローカルプレイヤーに対してのみ使用可能です。他のプレイヤーを強制的に座らせたり立たせたりすることはできません。
これを利用すれば、以下のようなギミックが実装可能です。
- 強制着席: 特定のエリアに入っ たプレイヤー全員を、映画館の座席に順番に座らせる。
- 乗り物の発車: 全員が座席に着いたら、ドアを閉じて乗り物を動かし始める。
- ゲームの敗退: ゲームで負けたプレイヤーを、観客席に強制的に移動させる。
まとめ
- プレイヤーを座らせたり、乗り物に乗せたりするには
VRCStationコンポーネントを使用します。 Station Enter Player Locationに割り当てたTransformの位置に、プレイヤーのアバターの基点が移動します。これを調整して座る位置を決めます。OnStationEnteredとOnStationExitedイベントは、ステーションの利用状況に応じて全プレイヤーで呼び出されます。- 誰かが使用中のステーションを他の人が使えないようにするには、
OnStationEnteredでDisableInteractive = trueにし、OnStationExitedでfalseに戻すのが最もシンプルな実装です。 - UdonSharpから
UseStation()やExitStation()を呼び出すことで、プレイヤーを強制的に座らせたり立たせたりする、より高度なギミックを構築できます。
ステーションは、ワールドに「生活感」や「目的」を与えるための基本ブロックです。カフェの椅子、乗り物の座席、イベント会場の観客席など、あらゆる場面で活用して、プレイヤーがワールドの一部になったかのような体験を提供しましょう。