Setting up NVIM for Unity development
Specifically for Linux. I'm using Ubuntu 22.04 and Unity 2021.3.22f1, with nvim-lspconfig
.
This was a pretty heinous setup process, so I'm documenting this here to help others who want something similar. The actual setup process isn't too bad, but figuring out all the individual steps was difficult. I came across a few guides but some were out of date, or were geared towards Windows, or just didn't work for me.
I should also caveat that I'm writing this shortly after I got this setup working, so I may run into other issues with it once I start developing with it more. For example, there might be issues with new files. If I run into those problems and manage to solve them I'll update this post.
Requirements:
omnisharp-roslyn
, I'm usingv1.39.6
.mono
; but crucially not the one from the default package repos. You need to use their official repo; then install:apt install mono-devel mono-complete
.- The default Ubuntu package repo version doesn't include
MSBuild
so unless you use the official mono repo you'll get errors like "Could not locate MSBuild instance to register with OmniSharp." when runningomnisharp-roslyn
.
- The default Ubuntu package repo version doesn't include
The process:
- Download a release of
omnisharp-roslyn
(as mentioned above, I'm usingv1.39.6
). Extract it somewhere—for me, this was/opt/omnisharp-roslyn
. Therun
file in that directory is what will start the LSP server. - Configure
nvim
. For me this all goes in~/.vim/plugin/nvim-lsp.vim
, but you can change that to match your own preference. I'm including the whole file but the key parts are what follows-- Omnisharp/C#/Unity
. You must specify the path to theomnisharp-roslyn
run
script.
lua << EOF
local nvim_lsp = require('lspconfig')
-- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer
local on_attach = function(client, bufnr)
local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end
local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end
-- Omnicompletion
buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')
local opts = { noremap=true, silent=true }
buf_set_keymap('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
buf_set_keymap('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts)
buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
buf_set_keymap('n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
buf_set_keymap('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<CR>', opts)
buf_set_keymap('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<CR>', opts)
buf_set_keymap('n', 'gR', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
end
-- Omnisharp/C#/Unity
local pid = vim.fn.getpid()
local omnisharp_bin = "/opt/omnisharp-roslyn/run"
require'lspconfig'.omnisharp.setup{
on_attach = on_attach,
flags = {
debounce_text_changes = 150,
},
cmd = { omnisharp_bin, "--languageserver" , "--hostPID", tostring(pid) };
}
EOF
-
Then we need to generate the
.sln
and.csproj
files for our Unity project. There are two ways to do this:- Almost every other guide to this setup says you need to install Visual Studio Code to do this. This then requires that you go into your Unity project, go to
Edit > Preferences > External Tools
, then setVisual Studio Code
to be yourExternal Script Editor
. Finally, check all the boxes forGenerate .csproj files for:
, then pressRegenerate project files
. This will work, and it's what I tried first. - The alternative, which I found here, is to run
/opt/Unity/2021.3.22f1/Editor/Unity -batchmode -nographics -logFile - -executeMethod UnityEditor.SyncVS.SyncSolution -projectPath . -quit
in your project root folder (note that/opt/Unity/2021.3.22f1/Editor/Unity
is just where I installed the Unity Editor, so change that to point to your location). This will also work, and appears to work without installing VSCode. The only annoying bit is that a project can only be opened by one instance of the editor at a time, so this won't work if you already have your project open. Perhaps there's a way to call it from within Unity?
- Almost every other guide to this setup says you need to install Visual Studio Code to do this. This then requires that you go into your Unity project, go to
-
Finally, one issue I had was that for some reason
Assembly-CSharp.csproj
wasn't generated. This led to the Unity framework not being picked up byomnisharp
, with errors like "The type or namespace name 'UnityEngine' could not be found". This solved itself by creating a new C# file, e.g.Assets/Foo.cs
and then refreshing the project files in the Unity Editor (which I guess causes Unity to compile the scripts and then generate this missing file). No idea if this is necessary though.
Lastly, the LSP server is slow to start up on my machine. Something like 30 seconds. For Rust and TypeScript development I use this plugin, which gives me progress on those LSP servers' startups, but unfortunately it doesn't yet work for omnisharp
.
NB: Just a couple debugging tips if this doesn't totally work for you: :LspInfo
and :LspLog
from within nvim
can help you figure out what might be going wrong.