Search Instagram Twitter Facebook Spotify Grid Tag Date Folder Chat Pencil

MIDI Controller for Tweaking Variables

IMG_9205

Background

For the past 2 months, I’ve been focusing on game feel in RELATIVITY, trying to get the motion of falling, carrying boxes, and switching walls to feel good. To this end, I’ve implemented a Quake-style debug console to help me monitor variables and to change them from within the game, which is incredibly useful when I’m playtesting the game on my laptop.

Right before GDC, my friend Thew mentioned in a twitter conversation that he uses a MIDI controller for tweaking variables.

thew twitter conversation

This had actually never occurred to me before, and it was kind of mind blowing how brilliant of an idea it is. No more fiddling with values in the inspector during gameplay (which is awkward for a FPS game because it requires the use of the mouse, which is synced to the player head movement). And even with a debug console, I had to set the values explicitly, and with knobs and sliders, it gives much smoother control over the values.

MIDI Controller

The MIDI Controller I bought is the KORG nanoKontrol2. It sells on Amazon right now for about $40. When I bought it, it was $30, but there was no free shipping (it was $10), so I guess they’ve just absorbed the shipping cost into the retail price.

Korg_NanoKontrol2

Once you get the controller, you’ll also want to download the KORG KONTROL Editor Software, which is available for free on the Korg website.

The software allows you to change various settings such as the channel numbers for the different buttons, sliders, and knobs.

Below is a view of the Kontrol Editor, and what the default channel numbers are:

Korg editor kontrol

Setting it up with Unity

I’m using Unity 5 on Windows 7.

I found this wonderful plugin by Keijiro which lets Unity communicate with external MIDI Controllers.

I add the folders in the test branch to my Unity project and was able to get the demos running.

The demo scene ‘CC’ lets you move the different knobs and sliders to control rectangles on the screen.

Nothing happened with me for ‘Notes’. I think my controller didn’t have the right buttons/keys?

Anyway, figuring out how to get the value for the buttons was enough for me, and CC allowed me to do that.

One thing, though, I do get this error in my console:

console_error

Everything still runs, so I’m not really sure what the problem is.

I believe it has to do with these two files both being named ‘UnityMidiReceiver’ in the plugins folder:

unitymidireceiver

However, if I try to delete one of them, or change their settings or name, I get way more errors as a result.

If anyone knows what the issue here is, please let me know.

Code

The plugin is pretty sweet, and also gives you smoothing functions for all the dials.

To get the value for a knob or slider, you use a line like this:

1
value = MidiInput.GetKnob(0, filter);

The first parameter is the channel number, and ‘filter’ is the input filter, which can be ‘RealTime’, ‘Fast’, or ‘Slow’. RealTime means that the value of the slider moves with the slider itself, while fast and slow have smoothing functions, so the value trails behind the actual slider a bit.

Value Mapping Problem

The value for each channel goes from 0 to 1. For the sliders and knobs, its continuous. For the buttons, it’s binary.

When I first set up the controller, this was a bit of a problem, because the knobs and sliders weren’t always in the exact position that you wanted your values to start at.

Say for example you have a value for ‘Resistance’ that you want to tweak. In the inspector, you have ‘Resistance’ set to 0.5, but on the controller, the slider could be in any position, and not exactly halfway through.

As soon as you touch the slider, then the value gets set off. Likewise, if you set all the knobs and sliders to 0 when you start, then all your variables end up being 0, which is also annoying. This means you have to start from scratch everytime you tweak the values, instead of getting it close in the inspector, and then using the controller to finetune.

Another issue is that then your values are limited to 0 and 1, which is not always the case with variables. You can remap the values, but if you make it go from -10 to 10, the slider’s physical distance is still the same, which then makes it less precise.

The solution was suggested by Ezra, which is to make the knobs and sliders infinite:

ezra conversation

I made it so that if you’re holding down the ‘Stop’ button, then none of the changes to the sliders or knobs get added to the actual value of the variable. So if the slider has reached the top and you want to keep increasing the value, hold the ‘Stop’ button, bring the slider down, then continue from there.

Below is some example code where I’m reading value from one slider:

1
2
3
4
5
6
7
8
9
10
11
12
stopButton = MidiInput.GetKnob(42, filter); // this is the stop button

sliderInput = MidiInput.GetKnob(0, filter);

//determine difference w/ previous value to decide how much to add to or subtract from the actual value
float difference = sliderInput - previousSliderInput;

if (inputStopButton == 0) { // if stop button is not pressed
value += difference;
}

previousSliderInput = sliderInput;

In the above code, ‘value’ is the actual value of the variable we’re changing.

Results

Anyway, that’s the basics of getting the MIDI controller set up. Once that’s done, you can use it to pretty much tweak any variable that’s a float, from physics values to light intensity.

So far, I’ve just connected the sliders and knobs to variables in different shaders I’m using. What’s great is that you can also just fool around by randomly moving sliders and turning knobs to see what happens. Here are some results of the experiment:

I hope this is helpful! I’m really looking forward to tweaking values in the game and fine tuning everything from acceleration speed to the vignette blur distance.

Relativity_Game_Screenshot-2015-03-14_22-08-42 Relativity_Game_Screenshot-2015-03-14_22-13-13 Relativity_Game_Screenshot-2015-03-14_22-24-42

Final Tips

During GDC, I met Matt Boch, who is a creative director at Harmonix, and has worked on games like Fantasia, as well as the hardware for Dance Central and Rock Band. I told about getting a MIDI controller to tweak variables and he had a few tips:

1. Often times, we choose values that seem to ‘look good’. For example, when I look at a lot of the values I had in my code, they were often ‘clean’ numbers like 4, 3.5, or 80. In reality, what actually feels good may be something like 7.828312. Using a controller to tweak can really help you get the right numbers based on feel.

2. I told Matt about how because I worked with placeholder game feel for a long time and got used to it, it’s really hard for me to get a sense of what feels good now. He suggested setting the values to something that I know for sure is bad for a week, to “shock” myself out of the game feel, and then go back and tweak the values to get it right.

5 Comments

  1. That’s really, really cool, and I have to try it soon.
    I’ve got just a doubt. Since you are modifying the values at runtime, when you stop the Unity player they obviously return to the original value.
    Have you set the controller so it can save the values?
    If so, how?
    Thank you so much!

  2. Hey! Right now they do return to their regular values, so I just take a screenshot. You could very well just use player prefs to save it. Mostly I’m just lazy and haven’t gotten around to doing it, but it really wouldn’t be very difficult.

  3. Hey, regarding your issue of values “snapping” to whatever the controller is at: in addition to the “stop” button you already have, you may want to implement what a lot of music programs call “soft takeover.” Basically, if there is any mismatch between the internal value and the controller, the controller is ignored *until* you twist the knob/move the slider to match the internal value in the program. That way, you may have to do a little extra twisting for the controller to “catch,” but you’ll never have a surprising pop in values. Tough to describe verbally, here’s a relevant video from Ableton https://youtu.be/7UhlD3hLVf8?t=3m56s

  4. Thanks for the tip! I will look into implementing this.

  5. Hi, I love the write up you made above and came across it while researching ways to connect a MIDI device to unity for control of transform elements.
    I know this post is from a while back but, I followed the steps above and was able to get input for a short time, however, after a few presses of the controller, Unity crashes with a “Fatal error in gc: too many threads”. Wondering if you’ve seen this and would have an idea on a fix..
    A long shot, I know, but thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.