Unity3D and Vim on GNU/Linux - Part 1
Apparently the Unity game engine isn’t done following me yet. In my new position I’m again tasked to work with it extensively. Despite my limited appreciation for it, I decided to make my time using pleasant by customizing the script edition process as much as I could.
In the recent month, an official build of the editor has been made available for GNU/Linux and I’m now using it on my personal machine running Arch Linux. With this came the possibility to use a proper vim installation to edit scripts for Unity. This is what this article will focus on.
Observing the original behavior
First it’s a good thing to observe how Unity usually handles external editors. It doesn’t matter if you’re using Visual Studio or Mono Develop, those two will act more or less in the same fashion when called from Unity.
When selecting a file for edition, the editor is launched if it isn’t already and depending on the context, you’re put directly on the line of interest.
Exploring the vim remote feature
In order to replicate that behavior with command line vim, we need to learn a bit about remoting with vim. While it’s a lesser known option, vim can work in client/server mode. In this mode, you can name an editing session with a server name.
vim --servername NAME_OF_YOUR_SERVER_INSTANCE firstfiletoedit.txt
Once the server is running, uou can connect to it and submit commands and keystrokes to it with the help of its name.
vim --servername NAME_OF_YOUR_SERVER_INSTANCE --remote anotherfiletoedit.txt
You can learn more about vim remoting by browsing the vim documentation by entering
:h remote or by reading about it here.
A pretty nifty aspect of the server implementation is that if there is not remote server to connect to, a new one will be created on the spot. As such you can easily create the server and connect to it with the same command line. Using
--remote-silent will prevent vim from complaining from the absence of the server if it isn’t already running.
vim --server UNITY_SCRIPT_EDITOR --remote filetoedit.txt
Setting Vim as Unity’s script editor
Now that we know how we can emulate the proper edition behaviour, we should probably learn a bit more about the way Unity calls the external editors proper. This thread sheds some light on the subject.
The external editor can be set by selecting the executable to be run with the “External Scrip Editor” entry in the “External Tools” menu of the preferences window.
There you can select the external script editor and you can arrange the command line parameters.
$File will represent the file to edit and
$Line is for the line. Straightforward stuff.
Now idealy, you would be doing somehting like this:
/usr/bin/vim --servername UNITY_SCRIPT_EDITOR --remote-silent +$(Line) "$(File)"
This would work for
gvim instead of
vim, but since we want to go to the next level and have our editing session in a terminal window, we’re not done yet.
Now we want to launch a new instance of our terminal only if vim hasn’t been instanciated already. We can easily check for that by looking up ou server name using the
vim --serverlist | grep UNITY_SCRIPT_EDITOR
This is neat. Now we can create a simple shell script that checks if a session is running, if it isn’t, we open up a terminal, open up vim with the proper server name and if it is, we just ask the running server to open the new file.
#!/bin/bash echo "Openning "$1" at line "$2 if [ ! -z `vim --serverlist | grep UNITY_SCRIPT_EDITOR` ]; then vim --servername UNITY_SCRIPT_EDITOR --remote-silent +$2 $1 else urxvt -e vim --servername UNITY_SCRIPT_EDITOR --remote-silent +$2 $1 fi
Just save that script somewhere you’re not likely to delete it, select it from the preferences window and you should be good.
It should be mentionned that the terminal that I’m using is
urxvt, replace that part with the terminal emulator you’re using.
Now I can edit scripts with my favorite text editor without any problem. It’s awesome but not enough, I now have to look into contextual completion in order to replicate the level of functionality provided by Visual Studio… and this is something I’ll develop in another blog post later this week.