Unity3D & Visual Studio Express

frontpage_image

Unity3D & Visual Studio Express

If you’re a programmer, whether pro or hobbyist, chances are you care a lot about the editor or IDE you’re using to write your code. I know I do. I have used a few in my time, and some years ago I got to know MonoDevelop through my growing interest in Unity3D.

The MonoDevelop-Unity3D relationship is a strange one, the editor seem to be stuck at version 2.8.2, a custom build version that works reasonably well but is really starting to feel it’s age. At Unite 2013 we finally got to know that Unity 4.3 will indeed come with an upgraded MonoDevelop 4.0 editor.

I’ve had some minor issues with MonoDevelop; project wide searches can take minutes, a few crashes, a few errors in the debugger related to generic list inspection, slow IntelliSense updating and sometimes requiering saving the file before it will find newly defined variables, and lately I’ve gotten screen tearing when using pgup/pgdown. I think the last issue is what made me start looking for an alternative.

Visual Studio Express 2012 to the rescue. This is Microsoft’s free edition of their flagship IDE Visual Studio. Currently they are offering a variety of versions of it too. I use the desktop edition but there is also a web edition if you want to check out the new Azure cloud stuff and do HTML5, CSS, javascript and so on. There is also a windows 8 and a phone editon if you want to publish to phone or windows store. This tutorial is based on the desktop edition.

 

Features

vse1

This tutorial will show you how to get the following;

  • Open C# files in Visual Studio Express from Unity3D.
  • Supports multiple Visual Studio Express processes running.
  • Go to Line selected in the Unity3D console.
  • Full IntelliSense / Color Highlighting support
  • Compile directly in Visual Studio Express.

This tutorial will not solve the following;

  • Unityscript & Boo files will not be handled, they will instead be opened in MonoDevelop as before.
  • Debugging, but MonoDevelop can do this as before.

 

Alternative Solutions

A better solution might be to use the full version of Visual Studio Pro along with UnityVS, but that is going to cost you about $7-800 for VS Pro and $99 for UnityVS. There is also Sublime Text, which apparently might be set up to work as a well integrated solution. I also keep forgetting to try out the new MonoDevelop 4 and Xamarin looks very interesting. I suppose those will be worthy IDE’s to test out some day.

There is also UnityEditor.Callbacks.OnOpenAsset that was introduced in 4.2 that allows us to override default behaviour on opening files directly inside Unity. I wrote a version of the wrapper to do this but it was very slow and it seemed to open a command console even when explicitly told not to. I didn’t pursue this venue any further, but I added references to reading materials on the subject at the end of the blog for those interested.

 

Tutorial Overview

  • Install Visual Studio Express 2012
  • Compile a wrapper that will automate VSE.
  • Rename MonoDevelop.exe to MonoDevelopReal.exe
  • Replace MonoDevelop.exe with our wrapper.

Target Audience

People who love C#, Unity and Visual Studio express, and who don’t really care all that much about javascript/boo. Also I don’t recommend this to anyone who aren’t tech savvy. Don’t break your MonoDevelop.exe and come running to me! :-)

 

Automating Visual Studio Express from Unity3D

So why do we need all this complicated stuff? Can’t you just change to an external editor in the unity preferences? Yes, you can but unity will not send project and line number parameters to external editors. This is kind of silly, and should imho be a setting that could be turned on/off. The result is that we need to build a wrapper that will be called instead of MonoDevelop.exe, it will interpret the parameters and take the appropriate action we want and route the parameters to Visual Studio Express with .cs files and pass them on to MonoDevelop for .js files.

The technology we will use to make the magic happen is the EnvDTE COM library. However first thing first. We are going to build our tool to automate VSE by using Visual Studio Express itself, so head on over to Microsoft and download Visual Studio Express for Desktop;

 

Step 1: Download and install the IDE.

DOWNLOADVisual Studio Express 2012 Desktop Edition

If you do not have a VS installed and don’t care about DTE techno babbling, proceed to step two.

Note that if you already have a version of VS installed and you install an additional version then you will get two versions and an version selector installed. This is awful and means that when you open a .cs file and you don’t have any VS running you will get a question about what VS version you want to use. So I recommend you to only have one version on your computer. If you already have a VS installed, the simplest solution is probably to just find the DTE programmatic ID of your VS version and use that. If you have no idea what that means, it simply means that when VS runs it registers itself in a register of sorts and we can ask that register if any programs/versions are running and what they are doing and so on and so forth. It’s really quite cool.

rot_list

Here is an example of the Running Object Table on my machine at the time I am writing this blog. As you see I have two VS projects running in two different visual express processes. This is the table the unity editor wrapper will use to determine if the file you want to open is already open, figure out the process that it’s open in and then give commands directly to that process to bring up the file and go to the line we want.

 

Step 2: Download the wrapper source code.

  • DOWNLOAD: UnityVSEWrapper.rar (the source code you will build the wrapper from)
  • Uncompress the archive file and double click the .sln file and make sure it opens with VSE.
  • If it doesn’t default to VSE then ‘Open With’ and select ‘Always open with’ (It’s important that it does)

Step 3: Modify the source to suit your needs.

  • Line 35: Change the ProgID if you use another VS edition
  • Line 37: Change the path of the output file if you plan on debugging
  • Line 40: Increase the retry counter if you have a slow machine or if you plan on using the VS version selector
  • Line 43: Toggle debug mode on/off

Step 4: Build & Deploy

  • In the solution explorer of VSE right click ‘References’ and select ‘Add References’
  • Search for ‘envdte’ and select EnvDTE and EnvDTE80
  • In the solution explorer open properties of your project and change Assembly Name to MonoDevelop
  • Hit F7 to build the project
  • Open a file explorer to Program Files (x86)/Unity/MonoDevelop/bin/
  • Rename MonoDevelop.exe to MonoDevelopReal.exe (.js files etc are sent to the ‘real’ monodvelop)
  • Rename MonoDevelop.exe.addins to MonoDevelopReal.exe.addins
  • Rename MonoDevelop.exe.config to MonoDevelopReal.exe.config
  • Copy <your project dir>/bin/debug/MonoDevelop.exe to Program Files (x86)/Unity/MonoDevelop/bin/

add_refs

 

Step 5: Open a C# file in Unity

Now if all things have gone according to the plan you should be able to switch over to unity and open a file like you normally do and if you double click on a warning or an error in the console you should be taken to that line number.

You might also want to test that opening .js files take you into ye olde MonoDevelop 2.8.2 (now being MonoDevelopReal.exe)

Note: Unity solutions often contain multiple projects.

Unity solutions usually contain 4 projects; CSharp, CSharp-Editor, UnityScript, UnityScript-Editor (probably 2 Boo versions too if you’re into that). You want to just delete the UnityScript ones in VSE if you want to compile directly there. Just don’t try to manage the project file yourself, Unity will do that for you. Simply delete the UnityScript & UnityScript-Editor projects from the solution explorer.

Unity 4.2 & UnityEditor.Callbacks.OnOpenAsset

In 4.2 Unity came with a new features allowing us to intercept the default opening of any asset, and since .cs files are assets this means we could put our wrapper directly inside Unity. I did some experimening with getting automation to work inside of unity but it mostly just crashed the entire editor. Sending files directly to VS did however work but it was very slow and seemed quite inferior to the wrapper I had already in place. However this looks promising and might be the best way to do things in the future. Read more about it here:

http://unity3d.com/unity/whats-new/unity-4.2

http://unityvs.com/news/2013/07/23/script-opening-unity-4-2/

 

Useful References

These are some of the more helpful sites I used when creating this wrapper. If you want to make your own then this is the place to start browsing;

http://stackoverflow.com/questions/350323/open-a-file-in-visual-studio-at-a-specific-line-number

http://blogs.msdn.com/b/kirillosenkov/archive/2011/08/10/how-to-get-dte-from-visual-studio-process-id.aspx

http://msdn.microsoft.com/en-us/library/68shb4dw.aspx

http://msdn.microsoft.com/en-us/library/t6d9sf9k.aspx

http://stackoverflow.com/questions/2525457/automating-visual-studio-with-envdte?rq=1

http://forum.unity3d.com/threads/124995-Accessing-Open-Script-and-Goto-Line-fom-Error-in-Unity-Editor

http://answers.unity3d.com/questions/148862/unity-34-uniscite-go-to-line-error-number-broken.html

 

 

18 Comments

  • Thanks for the script & tutorial!

    I had to set my External Tools Preferences in Unity to the new MonoDevelop.exe for this to work.

    One question: I also have VS for Win 8 installed an I’m still getting the version selector on the first .cs call. It’s not terrible since it only occurs once, but would be nice if I could shut it off nevertheless.

    Could you please elaborate on the EnvDTEList? Where do I get that and /or how can I getmy VS progID to set correctly?

    Thanks,
    David

    • I am glad you like the tutorial. If you replaced the original built in MonoDevelop.exe that comes with Unity you should be able to use the “MonoDevelop (built in)” option, I can’t think of any other requirements. I’ve used this setup for some time now, but I haven’t tried it on anything other than win7, so I can’t say for sure how it is on win8.

      What I found when I dug around trying to use automation for Visual Studio Express was that it used a different ProgID than Visual Studio (VisualStudio.DTE), and I kept finding resources for VS but nothing about VSE so I figured I’d just take a peek in the ROT list while VSE was running. I used some code I found on stack exchange (http://stackoverflow.com/questions/14186330/get-current-visual-studio-instance-envdte-in-c-sharp?rq=1) compiled that into a command that I could run in ye olde cmd.exe.

      Please note that the ProgID is only used when looking for already open solutions. If you get the version selector this is probably happening when the program doesn’t find any open solutions, and launches a new process by way of opening the .SLN project file. The version selector is probably your default ‘open with’ program for .sln and has been installed when you installed a version of visual studio while already having another visual studio version on the computer. I got this issue after installing visual studio express for web when I already had visual studio for desktop on the PC, and I had to spend ages manually uninstalling unwanted visual studio components (via the windows uninstall tool, but still).

      EndDTEList is just a while loop over the ROT list, here is the code;

  • I can’t get this to work. When I try to open a .cs file a cmd prompt window opens and closes really quickly. I was able to take a screen shot of it to read what it says.

    “Parsing Args”
    “Failed To Parse Args”

    or something to that effect.

    Any idea on how to fix? Don’t know if it matters, but I’m using Unity 4.3 and my Unity folder is not called Unity, it’s called Unity_4(because I have multiple Unity’s installed). Thanks!

    • In 4.3 they did a major upgrade in the default editor from MonoDevelop 2.8 to MonoDevelop 4.0 and in doing so they may have changed how they open files, I can’t really say yet since I am still on Unity 4.2 and don’t plan on upgrading until my current project is done.
      The only other advice I can think of is make sure your Edit->Preferences->External Tools->External Script Editor = MonoDevelop (built in) and maybe do a check to see if you get the expected command line arguments. My program here expects 3 arguments to be ‘–nologo’ ‘project file’ ‘source file;lineNumber’, so if they changed those you must change the wrapper accordingly.

  • It seems this only works if you already have the solution open in Visual Studio Express. Perhaps I just missed that part in your tutorial, or maybe they changed something. I changed the wrapper to print the number of args and what each one was, and with VSE closed, Unity only sends a single arg (the path to the project solution), but with VSE open, it sends the correct number of args.

    Not a big deal at all, considering it only takes about two seconds to open the solution.

    Thank you so much for this guide!

    • Thanks for your comments, I am glad someone finds my ramblings useful. I will get around to upgrading to 4.3 and testing this further once my next app is done, just don’t like changing my dev environment mid-project.

      Anyways, if it works with VSE open but doesn’t open VSE when needed, I’d advice;

      Did you set VSE to the default program for .sln files? Because the default behavior of the wrapper when it doesn’t find an open VSE is to launch the project file as a new process, kinda like if you double clicked the project file, then it will wait until VSE registers and pass stuff to it about which file to open and what line to go to.

  • Michael Miropoulos says:
    December 9, 2013 at 01:19

    Reply

    Hey Trond, awesome tutorial man, thanks a bunch!

    I have Unity 4.3.1 and Visual Studio Express 2013. Well, my little problem is that after opening the solution (as expected, clicking the file within Unity) it shows the following error: https://dl.dropboxusercontent.com/u/14380526/pipe_fantasy_UnityVSEWrapper_Error.PNG

    It does that every time I try to open a file within Unity. The thing is that it works great! It opens the file inside the already opened solution, which is awesome! But it does shows that error.

    You have my e-mail if you need to ask me more about it (or you can do that from here).
    Thanks for that again!

    • Michael Miropoulos says:
      December 9, 2013 at 03:00

      Reply

      Well, I found what was wrong. It was the Debugging process! 😛 I turned the DEBUG to false and everything is crazily awesome now! No errors and it’s just doing its stuff! 😀 You rock man! Thanks a bunch! 😀

  • Had to re do the process when updating to a new version of Unity, and I couldn’t find the wrapper I had created earlier. I’m glad though!

    You were right, the issue was with setting VSE as the default sln file opener. Also, I was also getting the same error as Michael, and setting debug to false fixed it. Thanks to both of you!

  • Great wrapper, but there seems to be a problem with it: when you change a CS file, the Unity Editor doesn’t seem to notice and wont compile the new version.
    Is there a way to fix that? Or am I doing something wrong?

    • It should notice when it gets focus, it’s the same as with MonoDevelop, notepad, or any other editor in my experience. I kinda like to keep some warnings in my code, like an unused variable or unreachable code, just to get that confirmation that stuff gets compiled. I hope you figure it out, let me know if I can help.

      • Nevermind I found the issue, it was a problem with the way I handled metadata, nothing to do with the wrapper.

        It works perfectly, thank you so much for it.

  • Windows 7_Unity 4.3.4f1 everything works fine and it’s great!
    Thank you so much! You’re done!

  • Francis Bourre says:
    March 27, 2014 at 09:13

    Reply

    Hi, I tried the whole thing with VisualStudio Express 2013 and Unity 4.3.4f1. When I double-click on C# file it told me that UnityVSEWrapper stopped running. Do you you know what goes wrong ?

  • Francis Bourre says:
    March 27, 2014 at 09:26

    Reply

    It’s working when debug is toogled to false.

  • Thanks for a very cool tool Mr Sausjord! Works without issue – once I changed line 37 to a valid location on my computer! 😀

  • Awesome, saved my time = saved my life!!

Leave a Reply

Your email address will not be published. Website Field Is Optional