MonoDevelop’s Assembly Browser – Decompile managed plugins

MonoDevelop offers a great but often unnoticed feature for decompiling C# libraries: The Assembly Browser.

The Assembly Browser decompiles managed code and displays it in your MonoDevelop IDE.

Think of plugins from the Unity Asset Store or other third-party modules: Many tools come as a pre-compiled package, such as Dynamic Link Library (.DLL). While you can import and use these libraries easily in Unity, you can’t just open their files and look at the scripts underneath, or can you?

Let’s take a look under the hood of Unity and disassemble one of MonoBehaviour’s methods:

  1. Copy the code to a new C# script in Unity and open it in MonoDevelop.
  2. Place the text cursor within the method name Lerp and right-click Go to declaration or hit Cmd/Ctrl + Y.
Go to declaration of Mathf.Lerp().
Go to declaration of Mathf.Lerp().

When inspecting a MonoBehaviour method, this will take us to the Assembly Browser, since all Unity functions are part of our current Assembly.

Inspecting Mathf.Lerp with MonoDevelop's Assembly Browser.
Inspecting Mathf.Lerp with MonoDevelop’s Assembly Browser.

 

You’re not allowed to alter Unity methods directly, but via the Assembly Browser you can take a look at many implementations.

Inspecting the disassembled Mathf.Lerp(), you can see exactly how it works. This comes in handy when deciding on which implementation is the right for your project; sometimes the Unity MonoBehaviour methods might not be what you want.

Note, that the Assembly Browser only shows managed code.

In short: Managed code in Unity = C#

Managed code in Unity means C# and Java. These programming languages are easily decompiled by MonoDevelop, native code like C or C++, however, is not.

Since most of Unity’s inner workings are written in C++ or use other highly-optimized machine language libraries, there are many MonoBehaviour methods, which you can’t disassemble to their roots in MonoDevelop. Still, most of the time, the Assemble Browser will show you enough information to let you guess what is going on.

Here’s another example:

Vector3.Angle() in MonoDevelop's Assembly Browser.
Vector3.Angle() in MonoDevelop’s Assembly Browser.

Most functions from the Mathf or Vector3 class show us how they work in the Assembly Browser. I encourage you to occasionally look at the implementation of such methods when using them in your project. It can be incredibly helpful to understand the math behind these helpers, because one day you might want to use custom implementations that fit your needs exactly.

Disassembling third-party-plugins

Browsing through pre-compiled plugins from the Asset Store is just as simple as looking at MonoBehaviour methods:

  1. Open a Unity project and import a plugin.
  2. Open the project (Solution) in MonoDevelop by opening any script from the Unity editor or clicking Assets > Sync MonoDevelop Project.
  3. In MonoDevelop go to View > Solution to show the solution browser.
  4. A third-party plugin will show under References. Double click the file to open it in the Assembly Browser. Or just open View > Assembly Browser and find the plugin there.
  5. Make sure to set Visibility to All membersor else you will only see public variables.
  6. Methods and properties can usually be found in a main class with the same name as the plugin. (Look for the “C” on blue background icon to find classes.)

Use MonoDevelop’s Assembly Browser to decompile any managed library or plugin and learn from real-world examples!

Thank you for reading! I hope you found this quick tip inspiring.

MonoDevelop Basics

In this article, you will build a C# script from scratch and learn the most important tools in MonoDevelop.

Code completion

Also referred to as autocomplete or IntelliSense, code completion describes the greatest tool every created for programmers. By its name you alreasy know what it does, but we’ll go over the details soon.

First, open a Unity project and create a new C# script called Player. Next, open it in MonoDevelop by double clicking it and delete everything inside it. Now, let’s start from scratch:

This is all you need to define a class in C#. But before you start typing, follow these guidelines:

MonoDevelop code-completion.
MonoDevelop code-completion.

Type the first two letters of the word public and hit Enter to auto-complete it. From now on, there will be almost nothing that you have to type out in its full length. If auto-completion doesn’t pop up you can force it via a keyboard shortcut; in my case: CTRL + Space.

If you’re having trouble, check your preferences:

MonoDevelop code completion preferences.
MonoDevelop code completion preferences.

 

Continue to define your class by typing the letter and hitting Enter to autocomplete it to class. Names like Player are not (yet) in your auto complete list, so you’ll have to spell it out. But once you’re done with your class definition, you will also have access to Player in your code completion window.

In fact, auto completion is a list of all keywords that are currently available to you. This includes keywords from the C# language itself, such as public or class, as well as classes or variables, which you defined.

Next, we want our script to derive from the MonoBehaviour class, because this is what we need to make our script work as a component on a GameObject in Unity. If you try to type out the keyword, there won’t be any auto complete suggestions at the moment. This is, because MonoDevelop doesn’t know about Unity’s MonoBehaviour at the moment. Let’s tell it:

Remember to only type the first few letters and then autocomplete with Enter.

UnityEngine is a collection of classes. MonoBehaviour is one of the classes that live within the UnityEngine namespace. Now, we can use auto completion to inherit from MonoBehaviour and give our class access to all the Unity goodies.

Now we have a functioning class. Save your file and check for errors in Unity, by attaching your script to a GameObject in the scene and hitting Play. Open the console window to see, if any errors appear in the log.

Continue with the following example:

For testing purposes, we will define another class within the same C# script. In fact, this is not a unusual thing to do, just be aware of the fact, that only the first class in a file can be a MonoBehaviour. Following MonoBehaviours will just not work correctly, although no error is shown in Unity.

Construct a new instance of the Test class in the Start() method and store a reference to it in a variable called test of the Type Test.

If this does not yet make sense, don’t worry, just copy the code and follow along to learn more about auto completion.

Code completion showing class members.
Code completion showing class members.

 

Now that we a class instance called test, we can use the dot-operator to access members (public variables) of that class.

Use auto completion to find your variables.

A short rundown of icons used in MonoDevelop’s auto completion:

  • M : method (function)
  • P : property
  • F : field (member variable)
  • C : class

(There are a few more icons, but I’ll save them for later.)

Here is our complete script with a print statement to see if it works correctly:

Checking variable values via the print statement is rather tedious and not very elegant. Click here to learn how to make private variable visible in the inspector.

Renaming variables and classes

If you ever want to rename a variable, be sure to use MonoDevelop’s renaming tool: Select your variable (highlight it or just place your cursor within it) and hit CMD/CTRL + R or right click Refactor Rename. This process is called refactoring because we don’t just want to rename a single word, but instead rename all instances of our variable.

Refactoring a class works the same way, but be aware that a class that derives from MonoBehaviour must have the same name as the file that is attached to a GameObject in the scene.

Shortcuts

Line endings