Overview
VRChat worlds only have meaning when players exist in them. Making gimmicks activate when players join the world or take specific actions within it makes the world more dynamic and attractive.
UdonSharp provides numerous events for detecting various happenings related to players. This article picks out the most important of these player events and explains their usage and application examples.
These events often take a VRCPlayerApi object as an argument, through which you can access information about the player who triggered the event (name, ID, etc.).
1. Player Join and Leave
Events for detecting players entering and leaving a world are fundamental to social features and game management.
OnPlayerJoined(VRCPlayerApi player)
- Execution Timing: Called on all players' clients in the instance when a new player joins the instance and loading is complete.
- Argument:
VRCPlayerApiobject of the joining player. - Main Uses:
- Displaying join logs (e.g., "Taro has joined").
- Updating player lists.
- Counting game participants and starting the game when capacity is reached.
OnPlayerLeft(VRCPlayerApi player)
- Execution Timing: Called on all remaining players' clients in the instance when a player leaves the instance.
- Argument:
VRCPlayerApiobject of the leaving player. - Main Uses:
- Displaying leave logs.
- Removing names from player lists.
- Electing a new master if the game master leaves.
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
public class PlayerJoinLeaveLogger : UdonSharpBehaviour
{
public override void OnPlayerJoined(VRCPlayerApi player)
{
// Only display message if the joining player is not yourself
if (player.isLocal)
{
Debug.Log("Welcome to the world!");
}
else
{
Debug.Log($"{player.displayName} has joined the world.");
}
}
public override void OnPlayerLeft(VRCPlayerApi player)
{
// Check if player doesn't exist (error prevention)
if (player == null) return;
Debug.Log($"{player.displayName} has left the world.");
}
}
2. Player Death and Respawn
For obstacle courses and combat games, you need to handle player death (falling, etc.) and respawn (revival).
OnPlayerRespawn(VRCPlayerApi player)
- Execution Timing: Called only on the respawning player's own client when the player clicks "Respawn" from the VRChat menu, or falls below the respawn altitude set in the VRC Scene Descriptor.
- Argument:
VRCPlayerApiobject of the respawning player. - Main Uses:
- Resetting health, score, and held items.
- Granting temporary invincibility on respawn.
Important: Calling
VRCPlayerApi.Respawn()from a script does NOT fire theOnPlayerRespawnevent. If you need additional processing when respawning from a script, design it to execute that processing directly just before or after callingRespawn().
// Example script for managing player health
public class PlayerHealth : UdonSharpBehaviour
{
private int health = 100;
// Custom event called when player takes damage
public void TakeDamage(int damage)
{
health -= damage;
if (health <= 0)
{
// Respawn if health drops to 0 or below
// Note: Respawn() doesn't fire OnPlayerRespawn,
// so call reset processing directly
ResetHealth();
Networking.LocalPlayer.Respawn();
}
}
// Processing to reset health
private void ResetHealth()
{
health = 100;
Debug.Log("Health fully recovered.");
}
// Called on menu respawn or fall
public override void OnPlayerRespawn(VRCPlayerApi player)
{
ResetHealth();
}
}
3. Avatar-Related Events
You can also detect changes related to avatars used by players.
OnAvatarChanged(VRCPlayerApi player)
- Execution Timing: Called only on that player's own client when a player changes their avatar.
- Argument:
VRCPlayerApiobject of the player who changed avatars. - Main Uses:
- Enabling/disabling gimmicks that only work with specific avatars.
- Measuring avatar height (scale) and adjusting gimmick behavior accordingly.
OnAvatarEyeHeightChanged(VRCPlayerApi player, float eyeHeight)
- Execution Timing: Called on all players' clients in the instance when a player's avatar eye height changes (during calibration, etc.).
- Main Uses:
- Adjusting UI position according to player height.
4. Pickup (Grabbing Objects) Events
Events also fire when players grab or release objects with the VRCPickup component attached.
OnPickup()
- Execution Timing: Called the moment a player grabs this object.
OnDrop()
- Execution Timing: Called the moment a player releases this object.
OnPickupUseDown() / OnPickupUseUp()
- Execution Timing: Called the moment the Use button (VR trigger, etc.) is pressed (
UseDown) / released (UseUp) while holding the object. - Main Uses: Implementing items operated while held, like gun triggers or flashlight switches.
// Example flashlight script
public class Flashlight : UdonSharpBehaviour
{
public Light flashlight;
// Toggle light when trigger is pulled while holding
public override void OnPickupUseDown()
{
flashlight.enabled = !flashlight.enabled;
}
}
Summary
- By using player-related events, you can create interactive gimmicks that respond to player actions and state changes.
OnPlayerJoined/OnPlayerLeftdetect player arrivals and departures and execute on all players.OnPlayerRespawndetects player respawns and executes only on the player themselves.OnAvatarChangeddetects avatar changes and executes only on the player themselves.OnPickupfamily of events detect grabbing, releasing, and using objects.- Many of these events take a
VRCPlayerApiobject as an argument, allowing you to get information about who triggered the event.
By mastering these player events, you can move from gimmicks that simply move to creating more immersive world experiences that are aware of player presence.