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.

Choose the correct path

MIDI is the direct route for triggering Udon world behavior. OSC uses VRChat's documented client and avatar endpoints.

  1. For a world, add a VRC Midi Listener and connect it to an Udon Behaviour.
  2. For an avatar or client control, enable OSC and send the documented address and value type.
  3. Verify the incoming data before connecting it to animations, lights, audio, or shared state.
Legacy video

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:

  1. Add VRC Midi Listener to a GameObject.
  2. Enable only the MIDI events the world needs under Active Events. No events are selected by default.
  3. Assign the receiving Udon Behaviour to the listener's Behaviour field.
  4. Add logic for MidiNoteOn, MidiNoteOff, or MidiControlChange.
  5. 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.

Keep high-rate controls bounded

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:

  1. The routed device appears in the VRChat SDK MIDI utility.
  2. Note and controller activity reaches the receiving Udon Behaviour.
  3. The received channel, number, and value match the intended track.
  4. 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:

  1. Import a .mid file and its matching audio clip.
  2. Assign the audio clip to the MIDI asset.
  3. Confirm the track BPM or use the documented BPM override.
  4. Add a VRCMidiPlayer.
  5. Assign the MIDI file, Audio Source, and target Udon Behaviours.
  6. 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:

  1. Enable OSC.
  2. Load the intended published avatar.
  3. Send the exact parameter address and compatible value type.
  4. Confirm the incoming message in OSC Debug.
  5. 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 -1 to 1 and must return to 0;
  • buttons use 1 for pressed and 0 for 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

Related Guides

Topics: VRChat worlds, Udon, MIDI, OSC, realtime control, avatar parameters