The class MidiKeyboard is available with the Pro version from the version 2.85 in order to read or write MIDI events from a MIDI keyboard connected to your computer.
If you only need to read MIDI messages from your device, perhaps you could prefer using the prefab MidiInReader (based also on MidiKeyboard class).
Setup
For connecting external MIDI device, Unity needs a plugin in order to propose core functions as list, select, open devices, write or read MIDI messages.
Download MidiKeyboard_V1.2.1_Plugins.unitypackage.zip here
- Unzip to get the unity package file inside the downloaded file.
- Import this package in your Unity editor (see Unity documentation). You will get something like that in your Project window:
- Remove unused plugins. For example for a recent Mac with Silicon CPU, keep only MacOSSilicon folder.
Known limitations:
- Tested with:
- Windows 10 or higher, CPU 64 bits.
- MacOS 10.1 or higher, CPU Intel/AMD CPU or Apple Silicon (M1, M2, ..).
- Not available on Android and IOs.
- Not able to process Sysex messages (perhaps in the future if there is a need!)
Demo
As usual with Maestro MPTK, a demonstration is available. In fact, it’s a very simple demonstration but which contains the main functions that you could have the need.

Thank to Giuseppe and his free asset ScreenLogger which was helpful to build this demo and test it on device.
Class MidiKeyboard
The class MidiKeyboard is static. Cool, there is no need to allocate object. We like simple thing! This page could also help you for writing script for MPTK.
On top of that, the schema is classical and you will find all the details of the class MidiKeyboard in the API Reference like:
- List devices
- Open the selected device
- Read or write to the device
- Close the device
API Reference for the class MidiKeyboard
See below an extract of the demonstration script. The most important methods from the class MidiKeyboard are highlighted.
private void Start(){
// Midi Keyboard need to be initialized at start
MidiKeyboard.MPTK_Init();
// Log version of the Midi plugins
Debug.Log(MidiKeyboard.MPTK_Version());
// Open or close all Midi Input Devices
ToggleRead.onValueChanged.AddListener((bool state) =>
{
if (state)
MidiKeyboard.MPTK_OpenAllInp();
else
MidiKeyboard.MPTK_CloseAllInp();
CheckStatus($"Open/close all input");
});
// Read or not system message (not sysex)
ToggleMsgSystem.onValueChanged.AddListener((bool state) =>
{
MidiKeyboard.MPTK_ExcludeSystemMessage(state);
});
// Read preset value and send a midi message to change preset on the device 'index"
InputPreset.OnEventValue.AddListener((int val) =>
{
int index = InputIndexDevice.Value;
// send a patch change
MPTKEvent midiEvent = new MPTKEvent()
{
Command = MPTKCommand.PatchChange,
Value = InputPreset.Value,
Channel = InputChannel.Value,
Delay = 0,
};
MidiKeyboard.MPTK_PlayEvent(midiEvent, index);
CheckStatus($"Play PatchChange {index}");
});
}
// Open a device for output.
public void OpenDevice() {
index = InputIndexDevice.Value;
MidiKeyboard.MPTK_OpenOut(index);
CheckStatus($"Open Device {index}");
}
// Play ore note
public void PlayOneNote(int random) {
MPTKEvent midiEvent;
int index = InputIndexDevice.Value;
// playing a NoteOn
midiEvent = new MPTKEvent() {
Command = MPTKCommand.NoteOn,
Value = InputNote.Value + random,
Channel = InputChannel.Value,
Velocity = 0x64, // Sound can vary depending on the velocity
Delay = 0,
};
MidiKeyboard.MPTK_PlayEvent(midiEvent, index);
CheckStatus($"Play NoteOn {index}");
// Send Notoff with a delay of 2 seconds
midiEvent = new MPTKEvent() {
Command = MPTKCommand.NoteOff,
Value = InputNote.Value + random,
Channel = InputChannel.Value,
Velocity = 0,
Delay = 2000,
};
MidiKeyboard.MPTK_PlayEvent(midiEvent, index);
// When event is delayed, last status is sent when event is send, so after the delay!
}
// Read message from the keyboard
private void Update() {
if (ToggleRead.isOn) {
// Process the message queue by max 100 to avoid locking Unity
while (count++ < 100) {
// Parse the message.
MPTKEvent midievent = MidiKeyboard.MPTK_Read();
// No more Midi message
if (midievent == null)
break;
Debug.Log($"[{DateTime.Now.Millisecond:00000}] {midievent}");
}
}
}
Code language: C# (cs)