MIDI and OSC in VRChat: Current Setup Guide
MIDI and OSC connect VRChat to instruments, sequencers, control surfaces, and external applications, but they use different systems. Use a VRC Midi Listener and Udon MIDI events for realtime control inside a world. Use VRChat's OSC interface for avatar parameters or supported client input addresses.
MIDI is the direct route for triggering Udon world behavior. OSC uses VRChat's documented client and avatar endpoints.
- For a world, add a VRC Midi Listener and connect it to an Udon Behaviour.
- For an avatar or client control, enable OSC and send the documented address and value type.
- Verify the incoming data before connecting it to animations, lights, audio, or shared state.
The companion video demonstrates an older SDK2 trigger workflow. Keep it as historical routing context, but build current world behavior with the Worlds SDK, Udon, and the VRC Midi Listener described below.
Video Companion
Creator: akalink
Video: MIDI and OSC Trigger Tutorial
MIDI and OSC Are Separate Routes
| Goal | Current VRChat route | Data received by |
|---|---|---|
| Play world lights from a MIDI keyboard | Realtime MIDI | Udon MIDI events |
| Drive world visuals from a DAW or sequencer | Realtime MIDI through a MIDI output visible to VRChat | Udon MIDI events |
| Play a prepared MIDI track with matching audio | MIDI playback | VRCMidiPlayer target behaviours |
| Change an avatar expression parameter | OSC avatar parameters | Local avatar parameter |
| Send movement, jump, use, or other supported client input | OSC input controller | Local VRChat client |
| Inspect an OSC address and value | OSC Debug | Local debug display |
The OSC documentation exposes input and avatar-parameter APIs. It is not a replacement for VRC Midi Listener when an Udon world needs note or controller events.
Realtime MIDI Scene Setup
Create one listener object and keep the world behavior in a separate Udon Behaviour:
MidiWorldController
├── VRC Midi Listener
│ ├── Active Events
│ └── Behaviour → MidiReceiver
└── MidiReceiver
└── Udon Behaviour or UdonSharp Behaviour
Set it up in this order:
- Add VRC Midi Listener to a GameObject.
- Enable only the MIDI events the world needs under Active Events. No events are selected by default.
- Assign the receiving Udon Behaviour to the listener's Behaviour field.
- Add logic for
MidiNoteOn,MidiNoteOff, orMidiControlChange. - Select the MIDI device through the VRChat SDK's MIDI utility for Editor testing.
VRChat creates its internal MIDI handler automatically when the scene starts. Do not add that handler manually.
Understand the MIDI Events
| Event | Inputs | Typical use |
|---|---|---|
MidiNoteOn |
channel 0–15, note 0–127, velocity 0–127 | Start a light, animation, particle, or audio action |
MidiNoteOff |
channel 0–15, note 0–127, release velocity | Stop or release an action |
MidiControlChange |
channel 0–15, controller 0–127, value 0–127 | Map a knob, fader, pedal, or button |
Use the channel and note or controller number together as the mapping key. Do not assume every device sends the full note range, release velocity, or the same values from an endless encoder.
MidiNoteOn(channel, number, velocity)
↓
Does channel match?
↓ yes
Does note number match?
↓ yes
Map velocity to the intended effect
Start by logging or displaying the received values. Connect the event to the final effect only after the channel, number, and range are confirmed.
Map Notes, Knobs, and Faders
Keep device mappings in a compact table beside the project:
| Control | MIDI message | World response |
|---|---|---|
| Pad 1 | Note On/Off, chosen channel and note | Flash one light |
| Keyboard key | Note On/Off, chosen channel and note | Play and release an animation |
| Fader 1 | Control Change, chosen controller number | Set emission or audio level |
| Transport button | Note or Control Change from the device | Start a defined sequence |
Normalize controller values before applying them to a property with another range. A MIDI value of 0–127 should not be passed directly to a Unity property that expects 0–1 without conversion.
Faders and knobs can produce many updates. Apply a meaningful threshold or rate limit before using those values for networking, and synchronize the resulting world state rather than every raw MIDI message.
Connect a DAW or Sequencer
A DAW such as REAPER can drive the current MIDI listener when its MIDI output appears to the operating system as an input device that VRChat can open.
DAW or sequencer
↓
MIDI output or virtual MIDI route
↓
Device visible to the VRChat MIDI utility
↓
VRC Midi Listener
↓
Udon MIDI events
The DAW and virtual MIDI configuration depends on the software and driver. Use this acceptance test:
- The routed device appears in the VRChat SDK MIDI utility.
- Note and controller activity reaches the receiving Udon Behaviour.
- The received channel, number, and value match the intended track.
- Stopping playback produces the required Note Off or reset state.
If the device does not appear in the MIDI utility, fix the operating-system or DAW routing before changing the Udon graph.
Select the Runtime MIDI Device
In a world with MIDI events, VRChat attempts to open the first MIDI device it finds on the local machine. When several devices are present, the official launch option accepts a partial, case-insensitive device name:
--midi=deviceName
The selected hardware or virtual device belongs to the local client. If MIDI should change shared world state, send the accepted result through the normal Udon ownership and synchronization path.
Local MIDI input
↓
Validate and map the value
↓
Request change from the state owner
↓
Owner updates synchronized variables
↓
All clients apply the shared result
Keep purely visual performer feedback local when other players do not need the same value.
Use MIDI Playback for a Prepared Track
For a prerecorded performance, VRChat also provides MIDI playback:
- Import a
.midfile and its matching audio clip. - Assign the audio clip to the MIDI asset.
- Confirm the track BPM or use the documented BPM override.
- Add a
VRCMidiPlayer. - Assign the MIDI file, Audio Source, and target Udon Behaviours.
- Use the same Note On and Note Off event logic as realtime MIDI.
The SDK's MIDI Playback example is available through VRChat SDK → Example Central. It is a useful baseline for synchronizing world visuals to a prepared audio track.
Enable and Test OSC
Enable OSC in VRChat from Action Menu → OSC → Enabled. By default, VRChat receives OSC on port 9000 and sends it on port 9001.
External OSC application
↓ send to
127.0.0.1:9000
↓
VRChat OSC input or avatar parameter API
VRChat
↓ sends to
127.0.0.1:9001
↓
External OSC receiver
Open OSC Debug from the OSC section of the Action Menu to inspect incoming addresses and values. The debug display also enables OSC if it was disabled.
Use localhost for applications running on the same computer. A custom --osc=inPort:outIP:outPort launch option is available for other port or destination requirements.
Drive Avatar Parameters with OSC
Incoming avatar parameter addresses use this pattern:
/avatar/parameters/ParameterName
The parameter name must match an avatar parameter. Supported documented OSC value types for avatar parameter configuration are Boolean, Integer, and Float.
Use a published avatar when testing generated OSC configuration files. VRChat documents that Build & Test can use OSC but does not save the avatar OSC configuration file to disk.
Test one parameter before adding a complete control surface:
- Enable OSC.
- Load the intended published avatar.
- Send the exact parameter address and compatible value type.
- Confirm the incoming message in OSC Debug.
- Confirm the avatar parameter changes.
Use OSC as a Client Input Controller
Supported client inputs use /input/Name, such as /input/Jump.
Two reset rules are essential:
- axes use floating-point values from
-1to1and must return to0; - buttons use
1for pressed and0for released.
Leaving an axis at 1 can keep the action active. Sending repeated button presses without a release value does not create distinct presses.
Only use documented input addresses, and test whether the control applies to Desktop, VR, or both. The official input-controller page identifies platform-specific entries.
Current Migration Checklist
When rebuilding the SDK2 setup shown in the video:
| Legacy concept | Current replacement |
|---|---|
| SDK2 world trigger | Udon Graph or UdonSharp behavior |
| MIDI trigger component from the old workflow | VRC Midi Listener |
| Trigger response | Udon MIDI event logic |
| Global change assumed from local input | Owner-controlled synchronized variable or network event |
| OSC treated as a generic world trigger | Documented OSC input or avatar-parameter address |
| Unverified controller mapping | MIDI utility or OSC Debug inspection |
Rebuild the behavior rather than importing old SDK2 components into a current Worlds SDK project.
Test Matrix
| Test | Expected result |
|---|---|
| MIDI device selected in the Editor | Listener receives the enabled event types |
| Note pressed and released | Note On and Note Off map to the same channel and note |
| Fader moved | Control number remains stable and values stay in the expected range |
| DAW playback stops | Held visual or audio states return to their defined resting state |
| Runtime has multiple MIDI devices | The intended device is selected explicitly |
| OSC message sent to port 9000 | OSC Debug shows the expected address and value |
| Avatar parameter message sent | The matching local avatar parameter changes |
| OSC button pressed twice | A 0 release occurs between the two 1 press values |
| Shared MIDI-driven state tested with two clients | Both clients receive the owner-approved result |
Help! The MIDI listener receives nothing.
Confirm the device is selected in the VRChat SDK MIDI utility, enable the required Active Events on VRC Midi Listener, and assign the correct receiving Udon Behaviour.
Help! My device works in the DAW but not in VRChat.
Check whether the DAW output is exposed as a MIDI input device that VRChat can open. If it does not appear in the SDK MIDI utility, correct the DAW or virtual MIDI routing first.
Help! The wrong MIDI device opens in VRChat.
Use the documented --midi=deviceName launch option with a distinctive part of the intended device name. VRChat matches partial names without case sensitivity.
Help! A knob jumps or moves in the wrong direction.
Inspect the raw controller number and values. Some endless encoders report relative increments instead of a continuous 0–127 position, so their values require device-specific handling.
Help! OSC Debug shows nothing.
Open OSC Debug to enable OSC, confirm the sender targets the correct IP and incoming port, and verify that no other application is using the same port.
Help! An OSC button works only once.
Send 1 for the press and 0 for the release. A second 1 without a reset does not create a new button transition.
Help! Other players cannot see my MIDI-driven change.
Realtime MIDI is read by the local client. Route shared results to the owner of the synchronized world state, then serialize the accepted value for the other clients.
Official References
- MIDI in Udon
- Realtime MIDI
- MIDI playback
- MIDI Playback example
- VRChat launch options
- OSC overview
- OSC debugging
- OSC avatar parameters
- OSC as an input controller
- VRChat networking
Related Guides
- Udon Networking Decision Guide
- UdonSharp Guide
- ClientSim World Testing
- VRChat Prefabs
- World Creation
- VRChat Documentation
Topics: VRChat worlds, Udon, MIDI, OSC, realtime control, avatar parameters