【VRChat】Implementing Stations: Chairs, Vehicles, and Sittable Objects

Created: 2025-12-19

Implementing functionality to seat players at fixed positions. VRCStation component setup, enter/exit events, and application to vehicles.

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).

  1. Prepare Object: Place a 3D model like a chair or bed in the scene.

  2. Add VRCStation: Add the VRCStation component to the chair object. This alone enables the basic "sit" functionality.

  3. Add Udon Behaviour: Add an Udon Behaviour component 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: If true, players cannot exit the station by themselves (using movement keys). Used when you want to require calling ExitStation() from Udon to exit.
  • Station Enter Player Location: Transform specifying 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: Transform specifying the position players move to when exiting the station. Usually set to somewhere in front of the station.
  • Seated: If true, attempts to apply seated animation (sitting, lying, etc.) to the avatar. When true, Player Mobility automatically becomes Immobilize.

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. The player argument 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

  1. Add VRCStation and Udon Behaviour to the chair object.
  2. Set VRCStation's InteractionText to "Sit" and Seated to true.
  3. Create the SyncedChair.cs script 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) and ExitStation(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 VRCStation component to seat players or have them ride vehicles.
  • The player avatar's origin moves to the position of the Transform assigned to Station Enter Player Location. Adjust this to determine the sitting position.
  • OnStationEntered and OnStationExited events 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 = true in OnStationEntered and return it to false in OnStationExited.
  • Calling UseStation() or ExitStation() 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.