Category Archives: C++

Building a Windows Plugin for Unity: Lessons Learned

Here’s some fun trivia about Cosmic DJ: the way that we achieve our rock-solid musical timing and responsive tap input is by using an external audio engine that I wrote. Generally speaking I would not recommend doing this! However, it’s just not really possible to have perfect metronomic time if you are running your metronome in the main game loop. Fluctuations in frame rate mean fluctuations in the smallest timestep available to the metronome, so if a frame takes longer than a 16th note you’ll hear the rhythm get a little wonky! Anyway, that’s a separate discussion, I’m going to talk about all of the things I got caught on while trying to build this non-trivial plugin.

Develop in Visual Studio 2008

A major thing I got stuck on for a while was trying to build the plugin with Visual Studio 2010. It seemed reasonable enough to do so, but it turns out you must build the plugin against .NET 2.0, which was not something I was even able to select in VS2010. I attempted to install older versions of .NET to build against by searching around the Microsoft download site, but only wound up with installers that didn’t work properly in Windows 7. Visual Studio 2008, meanwhile, defaulted to .NET 2.0, so I used that. Other build settings that seemed to matter a lot were:

  • General > Common Language Runtime support => No Common Language Runtime Support
  • General > Charater Set => Use Multi-Byte Character Set
  • C/C++ > Code Generation > Enable C++ Exceptions => Yes (/EHsc)
  • C/C++ > Code Generation > Runtime Libarary => Multi-threaded (/MT)

Unity has a really simple example plugin in their documentation that I’d recommend simply copying all of the settings out of. It’s called Simplest Plugin and is linked under the Examples section of Build Plugins For Desktop Platforms in the Unity Manual. I suggest looking for this page in your local documentation, just to be safe.

Create A Single Project Solution

There are a couple other libraries included in the plugin that I wanted to statically link to, such as my own partial port of Minim to C++ (YMMV), and like you do I wanted to have a solution that included the vcproj for Minim as a sub-project. This turned out to be mostly problematic because of the very particular build settings required by Unity. I found it difficult to make sure all of my projects agreed in their settings and also linked together properly.

Put DLL Dependencies In The Correct Place

Windows doesn’t have audio file reading routines built-in (like CoreAudio does in OSX for instance), so we leverage a couple open source libraries to make this happen (libsndfile and mpg123 if you must know). Both of these libraries are distributed such that you link against a .lib, but the real code lives in a DLL that is loaded at runtime. Unity can handle this but not quite in the way you’d expect.

To work in the Editor: Any DLLs that your plugin depends on must be put in the top level of your Unity Project folder, not in Assets/Plugins as you might expect.

To work in the Standalone Player: Any DLLs that your plugin depends on must be put in the same folder as the exe file, which either means copying them by hand or writing a post-process script to copy them.

You Can Debug Your DLL Using Visual Studio

A cool thing: it’s possible to debug your plugin code in Visual Studio while the DLL runs in the Unity Editor. For your debug flavor you’ll want Runtime Library set to Multi-threaded debug (/MTd). With your project open in Visual Studio: start the Unity Editor, go to the Tools menu in Visual Studio and choose “Attach To Process…”, choose Unity.exe from the list (Visual Studio might hang out for a bit before becoming responsive again), set some breakpoints, and press Play on a scene in Unity that has a script that calls into your plugin. When you call into code that has a breakpoint, VS will catch it and you can inspect variables and do like you would normally do. Important: Unity won’t load your plugin until the first time a script calls out to it, so when you initially attach to the Unity process it’ll look like your breakpoints are inaccessible, which is true because the DLL hasn’t been pulled into the executable yet.

Use String Marshaling When Returning Strings

Behavior seems inconsistent across platforms with regard to how Mono deals with strings returned from plugin functions. In OSX it seems to work fine to return static strings, but in iOS and Windows this causes a problem when Mono tries to deallocate that memory. If you search around the web you’ll see that some folks recommend allocating a new string and returning that, so that everything is cool when Mono tries to deallocate it, but I was still getting crashes on Windows with that method. Instead, what you want to do is return a const char * from your plugin code and then have this in the C# binding:

Importantly, PtrToStringAnsi copies the string represented by the IntPtr and also expands characters to unicode, so now you’ve got a string that is made from managed memory and will not cause crashes when it goes away. Of course this means you definitely do not want to allocate a new string when you return one to Unity because that memory will be leaked.

WaveShaper for iPad Released!

Today I released my first sound making app for iPad!

WaveShaper is an app for iPad that allows you to load up any audio file and make crazy cool sounds with it. It’s a lot like record scratching, but totally maxed out. This video will do a much better job of explaining it than words ever will:

Visit waveshaperapp.com for more info, sound samples, and screenshots. Or just go buy it right now!

Minim Beta Build and Other News

Things have been quiet around here, but hands have not been idle.

Anderson Mills has been hard at work on features for the next release of Minim. His project at Numediart to build a Unit Generator framework for Minim has made fantastic progress. On Tuesday, we plan to merge these changes back into the main Minim repository and release a Beta build. As usual, documenting is the hardest part of the job and we wanted to give people the chance to work with the new music programming features while we chew through that.

Meanwhile, I’ve created an app for the iPhone with Heather Kelley and Amanda Williams that is currently part of an art show in Hong Kong called Technosexual Bodies. The app is called Body Heat and I will be posting more news about that soon, I hope.

Finally, as hinted at in my previous post, I started work on a C++ port of Minim. It’s only in the beginning stages and it’s only functional enough to be useful for the iPhone app, but you are welcome to have a look at the repository. I’m making no promises about when the port will be finished, only saying that it will be finished at some point. If you’d like contribute to the port, make a fork at Github and have at it!

The Dreaded Double Diamond

So I’m porting the graph packages from Ptolemy II to C++ and I’ve finally gotten to the point where I can unit test some of it. I was going to start writing tests for the Graph class but when I ran the suite I got errors about some missing implementation in the graph library. A couple of those were methods I did actually miss, but one of them turns out to be the result of multiple inheritance. When you read about multiple inheritance there’s always mention of the dreaded diamond. Well, after sketching out the inheritance tree I’ve discovered I have a case of the dreaded double diamond!

The Dreaded Double Diamond!

This is what the Java inheritance tree looks like. However, it should be noted that all of the Analyzer classes are Java interfaces, which means it makes perfect sense in Java. However, porting this over to C++ is a bit stickier. My initial response to it was “this is silly”, so I broke the Analyzer-Strategy connection and the CachedStrategy-GraphAnalyzer connection. This prettied things up quite a bit. However, now it’s come back to bite me in the ass!

Analyzer defines a pure virtual toString() method. CachedStrategy implements a virtual toSting() method but it is not overriding Analyzer’s because it is no longer deriving from Analyzer. SelfLoopStrategy also implements a virtual toString() method and I thought that this would work not only as an overriding method for the implementation in CachedStrategy, but also as the implementation required by Analyzer. But this is not the case. As it happens, elsewhere in the code, toString() is invoked on a GraphAnalyzer and it doesn’t know where to find the implementation. This makes sense after reading about the subtleties of multiple inheritance. The question I am faced with now is whether I want put the double diamond inheritance scheme back into the C++ code. It makes me a little uneasy is all, there’s this little voice in my head saying, “there’s got to be a better way!”

If I was to use the double diamond, I’m pretty sure the way to handle it would be for Strategy and GraphAnalyzer to inherit Analyzer virtually and then for CachedStrategy and SelfLoopAnalyzer to inherit from GraphAnalyzer virtually. This would give SelfLoopStrategy the responsibility of calling the constructors for GraphAnalyzer and Analyzer. Oh multiple inheritance gurus, have I got that right? Is there a better way?