unity-vrc-world-sdk-3

Installation
SKILL.md

VRChat World SDK 3 Guide

Table of Contents

Section Content Reference
Scene Setup VRC_SceneDescriptor, Spawn This file
Components Pickup, Station, Mirror references/components.md
Layers & Collision Layers, Collision Matrix references/layers.md
Performance Optimization guide references/performance.md
Lighting Lighting settings references/lighting.md
Audio & Video Audio, Video players references/audio-video.md
World Upload Upload workflow references/upload.md
Troubleshooting Problem solving references/troubleshooting.md
Cheatsheet Quick reference CHEATSHEET.md

Common Mistakes (NEVER List)

These cause silent world failures, performance disasters, or Quest incompatibility:

# NEVER do this Why it hurts Use instead
1 Enable Mirror by default (active on world join) Renders the entire scene twice — immediate FPS halving, catastrophic on Quest Default Mirror OFF; add UdonSharp toggle or player-triggered activation
2 Use realtime directional lights with real-time shadows Quest has no hardware shadow acceleration; each shadow caster costs 10-30 FPS Baked lightmaps + light probes; set lights to Baked or Mixed mode
3 Set Respawn Height at or above the world floor Player respawns → falls → respawns again → infinite loop; players cannot recover Set to an unreachable depth (e.g., floor at Y=0 → Respawn at Y=-100)
4 Skip "Setup Layers for VRChat" on a new project Layer collision matrix is wrong by default — players walk through walls, Pickups clip floors Run VRChat SDK > Builder > "Setup Layers for VRChat" before placing any colliders
5 Enable Post-Processing without Quest build profile Post-Processing is silently disabled at runtime on Quest but VRAM is still allocated Use separate Android build profile or guard assets with #if UNITY_ANDROID
6 Place more than 2 active video players simultaneously Each player adds significant decoding overhead; running >2 simultaneously is a common cause of frame drops and audio issues in practice Disable extra players at scene start; activate only the currently playing one
7 Use Unity Constraints or Cloth on Quest Both are disabled silently at runtime on Quest — animations freeze, cloth hangs in place Use Animator-driven transforms (no constraints) or remove cloth from Quest meshes
8 Upload without completing a lightmap bake Realtime GI calculates at runtime — 3-5× draw call overhead, unacceptable on Quest Always bake lights before upload; Progressive GPU lightmapper is fastest
9 Place player walkable surfaces on Default layer (0) Collision matrix is wrong by default — avatar physics collision is unreliable; players may clip through geometry Use Environment (layer 11) for all walkable geometry, walls, and floors
10 Use very high lightmap resolution for large areas without profiling Texture memory can spike significantly at high resolutions; a common cause of OOM crashes on mobile headsets Start at 10-20 texels/unit as a practical guideline; profile VRAM and adjust — official guidance says "keep lightmap resolution low" for Quest
11 Add VRC_UIShape to a Screen Space or Overlay Canvas VRC_UIShape requires World Space Canvas; other modes throw a runtime Unity error in VRChat — the UI renders visually but is not interactive, with no visible error to the world builder Set Canvas > Render Mode to World Space before adding VRC_UIShape

Reference Loading Guide

Load only what the task requires.

Task MANDATORY READ Optional Do NOT Load
Setting up a new scene from scratch components.md, layers.md upload.md audio-video.md, troubleshooting.md
Making objects grabbable (VRC_Pickup) components.md layers.md audio-video.md, lighting.md
Setting up seating (VRC_Station) components.md layers.md audio-video.md, performance.md
Optimizing FPS for Quest performance.md, lighting.md troubleshooting.md audio-video.md, upload.md
Adding audio or video player audio-video.md, components.md troubleshooting.md lighting.md, performance.md
Baking lights / lightmap setup lighting.md, performance.md audio-video.md, layers.md
World upload and publish upload.md troubleshooting.md audio-video.md, lighting.md
Debugging collision or layer issues layers.md, troubleshooting.md components.md audio-video.md, lighting.md
Mirror setup and configuration components.md performance.md audio-video.md, upload.md

Before Starting a New World — Design Decisions

These decisions shape every downstream choice. Make them first, before placing any component.

Decision Options Implication
Quest required? Yes / No Yes → Quest First philosophy applies from day 0, not as a retrofit
Expected player count? 1–8 / 9–40 / 40+ Affects spawn count, mirror policy, max video players
Primary interaction? Grab (Pickup) / Sit (Station) / Watch (Video) / Explore Determines which SDK components are mandatory
Lighting approach? Baked / Mixed / Realtime Realtime is only viable on PC-only worlds; all lights must be baked before upload
Networked objects? None / Physics (Pickup+ObjectSync) / State (UdonSynced) Determines sync architecture before Udon scripting begins

The most expensive mistake: Designing for PC and adding Quest "later." By that point, lighting resolution, material complexity, and mesh density are locked. The Quest port then requires rebuilding the entire lighting and material pipeline.


Design Philosophy: Quest First

Build for Quest and get PC for free. Build for PC and Quest becomes a separate project.

Quest (Meta Quest 2/3/Pro) defines the performance budget:

  • CPU/GPU: ~2× slower than PC VR; tile-based GPU with no hardware shadow maps
  • VRAM: ~4 GB shared with OS (vs 6–12 GB on PC); no HDR framebuffer
  • Thermal throttling: Sustained 100% GPU load causes clock reduction within minutes

If a world runs at 72 FPS on Quest with a single test client, it will typically run at 90+ FPS on PC — though results vary by shader complexity, CPU-bound workloads, and hardware differences. The converse rarely holds. Verify against the official VRChat optimization documentation before publishing.

NEVER optimize exclusively for PC with "Quest support added later" — by that point, lighting, materials, and mesh density are all locked to PC quality, and the Quest port requires rebuilding everything.

SDK Versions

Supported versions: SDK 3.7.1 - 3.10.3

SDK New Features Status
3.7.1 StringBuilder, Regex, System.Random
3.7.4 Persistence API (PlayerData/PlayerObject)
3.7.6 Multi-platform Build & Publish (simultaneous PC + Android builds)
3.8.0 PhysBone dependency sorting, Force Kinematic On Remote, Drone API
3.8.1 [NetworkCallable] events with parameters, Others/Self targets
3.9.0 Camera Dolly API, Auto Hold simplification, VRCCameraSettings
3.10.0 Dynamics for Worlds (PhysBones, Contacts, VRC Constraints)
3.10.1 Bug fixes and stability improvements
3.10.2 EventTiming extensions, PhysBones fixes, shader time globals
3.10.3 VRCPlayerApi.isVRCPlus, VRCRaycast (avatar), Mirror render-order fix ✅ Latest stable

Important: SDK versions below 3.9.0 are deprecated as of December 2, 2025. New world uploads are no longer possible with these versions.


Scene Setup

VRC_SceneDescriptor (Required)

Exactly one is required in every VRChat world.

[VRCWorld Prefab]
├── VRC_SceneDescriptor (Required)
├── VRC_PipelineManager (Auto-added)
├── VRCWorldSettings (Optional - movement speed settings)
└── AvatarScalingSettings (Optional - avatar scale limits)

All Properties

Property Type Description Default
Spawns Transform[] Array of spawn points Descriptor position
Spawn Order enum Sequential/Random/Demo (Demo: all players to Spawns[0]) Sequential
Respawn Height float Respawn height (Y axis) -100
Object Behaviour At Respawn enum Respawn/Destroy Respawn
Reference Camera Camera Player camera settings reference None
Forbid User Portals bool Disable user portals false
Voice Falloff Range float Voice attenuation range -
Interact Passthrough LayerMask Interact passthrough layers Nothing
Maximum Capacity int Max player count (hard limit) -
Recommended Capacity int Recommended player count (UI) -

Reference Camera Usage

// Usage:
// 1. Adjust Near/Far clipping (recommended for VR: 0.01 ~ 1000)
// 2. Apply Post Processing effects
// 3. Set background color

// ⚠️ MUST disable the Camera component after configuring — an active Reference Camera
//    renders a second viewport. VRChat reads only the camera settings, not its output.
// Assign the configured (disabled) Camera to VRC_SceneDescriptor > Reference Camera.

Spawn Points Setup

// Spawn points are empty GameObjects assigned to VRC_SceneDescriptor > Spawns array.
// Players enter facing the Z+ direction of the spawn Transform.

// VRChat-specific requirements:
// - At least 2-3 spawn points (for simultaneous joins — single spawn causes overlap)
// - Place slightly above the floor (~0.1m) to avoid floor collision on spawn
// - Keep clear of obstacles (VR player guardian area is larger than their avatar)
// - Account for VR guardian boundaries — desktop player sizes differ from VR

Required Setup Checklist

□ Exactly one VRCWorld Prefab exists in the scene
□ At least one Transform set in Spawns
□ Respawn Height set to an appropriate value (well below the floor)
□ Reference Camera configured for clipping distances (for VR)
□ Layer/Collision Matrix correctly configured
□ "Setup Layers for VRChat" has been executed

Components

MANDATORY READ references/components.md (~800 lines) before configuring any VRC component below. Load in full — dependency requirements and Udon event hooks are distributed throughout. Do NOT Load: references/audio-video.md, references/lighting.md.

Component Required Elements Purpose SDK
VRC_SceneDescriptor - World settings (required) -
VRC_Pickup Collider + Rigidbody Grabbable objects -
VRC_Station Collider Sittable locations -
VRC_ObjectSync Rigidbody Auto-sync Transform/physics -
VRC_MirrorReflection - Mirror (⚠️ high cost) -
VRC_PortalMarker - Portal to other worlds -
VRC_SpatialAudioSource AudioSource 3D audio -
VRC_UIShape Canvas (World Space) Unity UI interaction -
VRC_AvatarPedestal - Avatar display/switch -
VRC_CameraDolly - Camera dolly 3.9+

VRC_ObjectSync vs UdonSynced

Scenario VRC_ObjectSync UdonSynced variables
Throwable objects / physics ✅ Recommended
State only / complex logic ✅ Recommended

SDK 3.8.0+: Force Kinematic On Remote — Makes Rigidbody kinematic on non-owner clients, preventing unexpected physics behavior.


Layers & Collision

VRChat Reserved Layers

Layer # Name Purpose
0 Default General objects
9 Player Remote players
10 PlayerLocal Local player
11 Environment Environment (walls, floors)
13 Pickup Grabbable objects
14 PickupNoEnvironment Pickups that don't collide with environment
17 Walkthrough Walk-through objects
18 MirrorReflection Mirror reflection only
22-31 User Layers Available for custom use

Layer Setup Steps

1. VRChat SDK > Show Control Panel
2. Builder tab
3. Click "Setup Layers for VRChat"
4. Collision Matrix is automatically configured

MANDATORY READ references/layers.md when setting up collision or debugging physics. The default Unity collision matrix differs from the VRChat-correct one — always verify. Do NOT Load: references/audio-video.md, references/upload.md.


Performance

Target FPS

Platform FPS Target Measurement Point
PC VR 45+ FPS Spawn point, 1 player
PC Desktop 60+ FPS Spawn point, 1 player
Quest 72 FPS Spawn point, 1 player

Critical Limits

Item Recommended Reason
Mirrors 1, default OFF Renders the entire scene 2x
Video players Max 2 Decoding overhead
Realtime lights 0-1 Dynamic shadows are expensive
Lightmaps Required Performance foundation

Quest/Android Restrictions

Component PC Quest
Dynamic Bones ❌ Disabled
Cloth ❌ Disabled
Post-Processing ❌ Disabled
Unity Constraints ❌ Disabled
Realtime lights ⚠️ Avoid

Performance Optimization Workflow

If FPS is below target, follow this workflow — measure before guessing:

1. Measure
   ├── Unity Profiler: standard profiling in Play mode (primary; Deep Profile only for function-level deep dives — avoid on Quest, misleading results)
   ├── VRChat overlay: type "/perf" in-game
   └── Stats window: Draw Calls, Triangles, VRAM

2. Identify bottleneck category
   ├── CPU-bound (high Draw Calls): → Batching / LOD / Culling / Static flags
   ├── GPU-bound (shader cost): → Mirror / Realtime lights / Post-Processing
   ├── Memory (VRAM spikes): → Reduce texture resolution / video players
   └── Physics: → Disable Rigidbodies / Cloth / Constraints on Quest

3. Fix largest impact first, re-measure after each change
   (estimates below are typical ranges; actual gains vary by world complexity)
   Mirror ON by default    → Disable by default               (often -40-50% render cost)
   Realtime shadows        → Bake all lights                  (often -30-50% GPU cost)
   High lightmap resolution → Reduce and re-profile           (often -30-70% VRAM)
   Unbatched static objects → Mark as Static + enable batching (often -30-60% draw calls)
   Many active particles   → Pool; disable off-screen          (often -10-20% CPU)

Never stack multiple changes before re-measuring — you'll lose the ability to identify which change helped.

MANDATORY READ references/performance.md and references/lighting.md for Quest optimization. Run the profiling workflow above first to identify the bottleneck category before consulting references. Do NOT Load: references/audio-video.md, references/upload.md.


Lighting

Baked Lighting (Required)

✅ Recommended settings:
├── Lightmapper: Progressive GPU
├── Lightmap Resolution: 10-20 texels/unit
├── Light Mode: Baked or Mixed
└── Light Probes: Place along player paths

❌ Avoid:
├── Realtime lights (dynamic shadows)
├── High-resolution lightmaps (memory consumption)
└── Excessive Reflection Probes

MANDATORY READ references/lighting.md when configuring lightmaps or light probe placement. Do NOT Load: references/audio-video.md, references/upload.md, references/layers.md.


Audio & Video

VRC_SpatialAudioSource

Property Description Default
Gain Volume (dB) 0 (World: +10)
Near Attenuation start 0m
Far Attenuation end 40m
Volumetric Radius Source spread 0m
Enable Spatialization 3D positioning true

Video Player Selection

Feature AVPro Unity Video
Live streaming
Editor preview
YouTube/Twitch
Quest support

MANDATORY READ references/audio-video.md for VRC_SpatialAudioSource or video player configuration. Do NOT Load: references/lighting.md, references/performance.md.


World Upload

Upload Steps

1. Check Validation
   └── VRChat SDK > Build Panel > Validations

2. Build & Test (local testing)
   └── "Build & Test New Build"
   └── Supports multi-client testing

3. Upload
   └── "Build and Upload"
   └── Set Content Warnings
   └── Set Capacity

4. Publish settings
   └── Configure public/private on the VRChat website

Pre-Upload Checklist

□ VRC_SceneDescriptor × 1
□ Spawns configured
□ Respawn Height appropriate
□ Layer/Collision Matrix verified
□ Light baking complete
□ Mirror default OFF
□ 45+ FPS in VR
□ No Validation errors
□ Content Warnings set
□ Capacity set

MANDATORY READ references/upload.md before running Build & Upload. Verify all pre-upload checklist items first. Do NOT Load: references/audio-video.md, references/lighting.md.


Troubleshooting

Diagnostic Router

Identify the symptom category, then follow the diagnostic path:

Physics / Collision

  • Player walks through walls or floor
    1. Did you run "Setup Layers for VRChat"? (SDK > Builder tab)
      • No → Run it. The default collision matrix blocks player↔environment collision.
      • Yes → Is the geometry on the Environment layer (11)?
        • No → Move all walkable surfaces, walls, and floors to layer 11.
        • Yes → Open Physics > Layer Collision Matrix: Environment × Player row must be ON.
  • Pickup passes through floors / walls → Pickup must be on Pickup layer (13), not Default (0). In the collision matrix, Pickup × Environment must be ON.

Grab / Interaction

  • Can't grab Pickup at all
    1. Collider present? No → Add a Collider component.
    2. Rigidbody present? No → Add a Rigidbody component.
    3. VRC_Pickup component present? No → Add it.
  • Pickup grabbed but immediately released → Check DisallowTheft on VRC_Pickup. If the current holder already owns it, a second grab may be blocked.

Sync / Network

  • Pickup position doesn't update for other players → Add VRC_ObjectSync (requires Rigidbody). Without it, only the local client moves the object.
  • Pickup returns to original position on drop → Ownership is not being transferred. Verify VRC_Pickup or UdonSharp script calls Networking.SetOwner before moving.

Seated / Station

  • Can't sit in Station (no interaction prompt)VRC_Station requires a Collider on the same or a child GameObject to register the interaction ray.
  • Player clips into Station geometry after sitting → Adjust the Station Collision Transform field in the VRC_Station Inspector.

Mirror

  • Mirror doesn't reflect players or world → Open VRC_MirrorReflection > Layers. Must include: Player (9), PlayerLocal (10), MirrorReflection (18), Environment (11).
  • Mirror causes severe FPS drop → Remove unnecessary layers from the Layers mask, and ensure Mirror is OFF by default (see NEVER #1).

Build / Upload

  • SDK build error in VRChat Control Panel → Builder tab lists all ⚠️ and ✖️ blockers with descriptions. Resolve each before building.
  • "Missing script" on a UdonSharp component → The .cs file must have a matching .asset file. See the "missing .asset / script-asset pairing" rule in the unity-vrc-udon-sharp skill.

Editor / Runtime Discrepancy

  • World works in Unity Editor Play mode but fails or behaves differently in VRChat → Unity Play mode does not replicate all SDK behaviors. Use "Build & Test New Build" (SDK > Builder tab) — this launches the actual VRChat client locally. Editor Play is useful only for quick UdonSharp iteration.
  • Interactive UI element is visible but cannot be clicked in VRChat → VRC_UIShape on a Screen Space or Overlay Canvas (see NEVER #11). Set Canvas > Render Mode to World Space.

MANDATORY READ references/troubleshooting.md only if the Diagnostic Router above did not resolve the issue. Do NOT Load for non-troubleshooting tasks.


Related Skills

Task Skill to Use
C# code creation unity-vrc-udon-sharp
Network sync (Udon) unity-vrc-udon-sharp
Event implementation unity-vrc-udon-sharp
Scene setup This skill
Component placement This skill
Performance optimization This skill

Templates (assets/templates/)

Starter templates for common SDK component patterns. Each template compiles without modification; adjust Inspector fields and extend the event stubs for your world.

Template Purpose
VRC_Pickup_Rigidbody.cs VRC_Pickup with Rigidbody — OnPickup/OnDrop/OnPickupUseDown/OnPickupUseUp events, ownership transfer, audio feedback
VRC_Station_Basic.cs VRC_Station controller — OnStationEntered/OnStationExited events, PlayerMobility, force-eject API

References

File Content Approx. Lines
references/components.md All component details 800+
references/layers.md Layers & collision 400+
references/performance.md Performance optimization 500+
references/lighting.md Lighting settings 400+
references/audio-video.md Audio & video 400+
references/upload.md Upload procedure 300+
references/troubleshooting.md Troubleshooting guide 500+
CHEATSHEET.md Quick reference 200+
Related skills

More from niaka3dayo/agent-skills-vrc-udon

Installs
161
GitHub Stars
148
First Seen
Mar 12, 2026