Setting up and building a Unity class library (DLL) in Visual Studio

So what is a Unity class library and why should you care? Well in it's simplest form a class library is code precompiled into a DLL file that Unity can import and expose to your scripts. And why might you want to include precompiled code? In the Unity team's own words:

When developing your own code, you may be able to use compilers not supported by Unity (F#, for example) by compiling the code to a DLL and adding it to your Unity project. Also, you may want to supply Unity code without the source (for an Asset Store product, say)

ref: http://docs.unity3d.com/Manual/UsingDLL.html

Hence having a DLL will allow you to use languages and compilers other than C# or UnityScript, also allowing you to shorten the time Unity takes to compile your scripts because they are already precompiled and the reason I tend to use Unity class libraries is to protect my code when I distribute it in assets via the Unity Asset Store. Including a DLL in you Unity package means you don't have to distribute your intellectual property or risk someone modifying it in a way you didn't intend.

Setup

I'm going to walk you through the process of setting up a project in Visual Studio to compile a C# class library compatible with Unity on Windows. Doing the same in MonoDevelop, other IDEs and other platforms is not too far removed from what will be described below but unfortunetaly it is out of the scope of what I describe below.

The first step is to create or open up an existing Unity project and then click on Assets ➝ Open C# Project to open up the project's solution in Visual Studio (assuming you have setup Unity to use Visual studio as it's IDE.)

Next we want to add a new C# project to our solution in VS. Click File ➝ Add ➝ New Project... and in the dialog that opens we want to select a Visual C# Class Library.

Give your class library a name and specify a location to save it in (I normally create it at the root of the Unity project I'm using which is normally a project for an asset I'm building) then click OK.

Once added to your solution right click on the project you just created and click Properties in the window that just opened, then navigate to the Application section and under the Target framework: drop down, select Unity 3.5 .net Subset Base Class Libraries from the options.

To access classes from UnityEngine namespace in your library you may also want to add a reference to the UnityEngine.dll to your class library project. The dll can be found under you Unity install location at Editor\Data\Managed\UnityEngine.dll for Windows and Contents/Frameworks/Managed/UnityEngine.dll for OSX

At this point you should now be able to add a class, build your library and then drop the .dll file produced into your Unity's project Asset folder and be able to reference the class you just created and compiled in your Unity scripts. If you want you can copy the solution and project for your class library (removing the references to the Unity generated projects first) to another location letting you have this a seperate entity to your Unity project solution.

Debugging and simplifying the build process

So you now have a class library that you can build and access from your Unity scripts. The only problem now is that you can't debug the code in your library currently and you have to manually copy the dll over to your Assets folder every time you build the library.

Visual Studio generates a debug symbols file for you in the form of a pdb file in the output directory but Unity's Mono isn't compatible with pdb files so we have to convert it to Mono's mdb format.

Firstly you will need to install the latest version of Mono then add an environment variable to your system pointing MONO_PATH to the install location of Mono.

Next we add a post build event to the Properties of the class library under the Build Events section. You will see two text fields here labelled Pre-build even command line: and Post-build event command line:. In the Post-build event text field we will enter some commands to run after our library is built.

The first one will be echo ON this will ensure any output from our commands will be sent to the Output console in Visual Studio to help us see and keep track of what our commands are doing.

The second line will convert our pdb file to a mdb file using a utility found in you Mono installation. Add call "%MONO_PATH%\bin\pdb2mdb.bat" $(TargetPath) next, this command looks for a pdb2mdb.bat file in your MONO_PATH that you set up earlier, then generates a mdb file in your $(TargetPath) which is just the output path specified in the other settings for your project. This file can then be copied alongside the .dll into your Unity Asset folder and means you will now be able to debug your class library.

To avoid the need to copy the dll and mdb file each time we recompile the library lets add two final lines to the Post-build events to copy these files into the Unity Assets folder automatically. Do this by adding the line mkdir "$(SolutionDir)Assets\$(ProjectName)\" assuming your $(SolutionDir) is the root of your Unity project which is where Unity normally generates the solution for your project. And lastly copy /Y "$(TargetDir)$(ProjectName)*" "$(SolutionDir)Assets\$(ProjectName)\". These commands will create a folder for you under Assets named the same as your class library and then copy the build files over.

Once this is done your Properties Build Events section should look something like this:

echo ON
call "%MONO_PATH%\bin\pdb2mdb.bat" $(TargetPath)
mkdir "$(SolutionDir)Assets\$(ProjectName)\"
copy /Y "$(TargetDir)$(ProjectName)*" "$(SolutionDir)Assets\$(ProjectName)\"

Now whenever you build your class library the files will be copied over on a successful build and Unity will detect the changes and reload it's references for you, saving you precious time and hassle. So having completed all of the above you should now be in a position to build and include your own class libraries in your Unity projects!

IndyBonez

Read more posts by this author.