Overview
The ability for players to relax by sitting in chairs or travel by riding vehicles in the world gives players a role and dramatically increases immersion. In VRChat, this functionality of "constraining players to a specific position and pose" is achieved using stations (VRCStation).
By combining UdonSharp with VRCStation, you can create various gimmicks from simple chairs to moving vehicle seats, or even restraints that play special animations.
This article explains the basic usage of the VRCStation component and how to implement an interactive seating system integrated with UdonSharp.
Step 1: Setting Up the VRCStation Component
First, add station functionality to the object you want players to sit on (e.g., a chair model).
-
Prepare Object: Place a 3D model like a chair or bed in the scene.
-
Add
VRCStation: Add theVRCStationcomponent to the chair object. This alone enables the basic "sit" functionality. -
Add
Udon Behaviour: Add anUdon Behaviourcomponent to the same object to prepare for script integration.
Key VRCStation Settings
InteractionText: Text displayed when aiming at the station (e.g., "Sit").Player Mobility: Sets movement restrictions for the player while using the station.Mobile: Movement allowed. Used for vehicles.Immobilize: No movement. Used for fixing in place, like chairs and beds.
Can Use Station From Station: Whether this station can be used while using another station. Unchecking prevents jumping from chair to chair.Disable Station Exit: Iftrue, players cannot exit the station by themselves (using movement keys). Used when you want to require callingExitStation()from Udon to exit.Station Enter Player Location:Transformspecifying the position and orientation players move to when using the station. If not specified, uses the station object's own position. The avatar's origin (feet) comes to this position.Station Exit Player Location:Transformspecifying the position players move to when exiting the station. Usually set to somewhere in front of the station.Seated: Iftrue, attempts to apply seated animation (sitting, lying, etc.) to the avatar. Whentrue,Player Mobilityautomatically becomesImmobilize.
Position Adjustment Tips
- For
Station Enter Player Location, it's recommended to create and assign a separate empty GameObject. Name this empty object "EnterPoint" and make it a child of the chair object. - Adjust the "EnterPoint" position to find where the avatar looks natural when seated. Keep in mind that the avatar's feet will come to this point. The orientation (blue Z-axis) becomes the player's forward direction.
Station-Related UdonSharp Events
For objects with VRCStation attached, the following UdonSharp events are called when players use or exit the station.
OnStationEntered(VRCPlayerApi player): Called when a player starts using the station. Theplayerargument is the player who entered the station.OnStationExited(VRCPlayerApi player): Called when a player finishes using the station.
These events are executed on all players' clients in the instance, not just on the client of the player who entered the station. This allows all players to know when someone sits in a chair.
Example Implementation: Chair with Synced Usage Status
Implement a chair that is controlled so that others cannot sit while someone is seated. This is the most basic synchronization pattern for station gimmicks.
Script: SyncedChair.cs
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
public class SyncedChair : UdonSharpBehaviour
{
private VRCStation station;
// UdonSharp's Start is called at Unity's Awake timing
void Start()
{
// Get the VRCStation component attached to the same GameObject
station = GetComponent<VRCStation>();
}
// Called on all players when someone enters the station
public override void OnStationEntered(VRCPlayerApi player)
{
// Once someone enters, others can no longer use it
// DisableInteractive only needs to be set locally
this.DisableInteractive = true;
}
// Called on all players when someone exits the station
public override void OnStationExited(VRCPlayerApi player)
{
// If no one is using it, make it usable again
this.DisableInteractive = false;
}
}
Unity Setup
- Add
VRCStationandUdon Behaviourto the chair object. - Set
VRCStation'sInteractionTextto "Sit" andSeatedtotrue. - Create the
SyncedChair.csscript and assign it to the Udon Behaviour.
With just this, other players cannot interact with the chair while someone is sitting in it. Since DisableInteractive only needs to be set on each client individually, complex synchronization using [UdonSynced] variables isn't necessary in this case.
Application: Controlling Stations from Udon
Beyond just sitting via Interact, you can also force specific players to sit in a station from UdonSharp.
// station is a reference to the VRCStation component
// player is the VRCPlayerApi of the player you want to seat
// Seat the player in the station
station.UseStation(player);
// Make the player stand up from the station
station.ExitStation(player);
Note:
UseStation(player)andExitStation(player)can only be used on the local player. You cannot forcibly seat or stand up other players.
Using this, you can implement gimmicks like:
- Forced Seating: Sequentially seat all players who enter a specific area in movie theater seats.
- Vehicle Departure: Close the doors and start moving the vehicle once everyone is seated.
- Game Elimination: Forcibly move players who lose a game to the spectator seats.
Summary
- Use the
VRCStationcomponent to seat players or have them ride vehicles. - The player avatar's origin moves to the position of the
Transformassigned toStation Enter Player Location. Adjust this to determine the sitting position. OnStationEnteredandOnStationExitedevents are called on all players based on station usage status.- To prevent others from using a station while someone is using it, the simplest implementation is to set
DisableInteractive = trueinOnStationEnteredand return it tofalseinOnStationExited. - Calling
UseStation()orExitStation()from UdonSharp allows you to build more advanced gimmicks that forcibly seat or stand up players.
Stations are fundamental building blocks for giving your world a sense of "life" or "purpose." Use them in all kinds of scenarios—café chairs, vehicle seats, event venue spectator seating—to provide experiences that make players feel like they're part of the world.