reddit / emacs
Getting (Doom) Emacs to work with Unity on macOS (with Macports)
the_plonkmaster · 2022-11-16 00:37
Emacs is a perfectly good development environment, contrary to what the folks at Unity think. In fact, it’s better than any of the rubbish they shovel at you, but let’s not get too evangelistic. I’m running Doom Emacs on a Mac (using Macports as a package manager), and although there are some guides out there on getting Emacs to work with Unity, most of them didn’t get *everything* working for me, so I thought I’d write this guide to help others out. To use Emacs effectively with Unity means setting up LSP Mode integration. In order to do that, you’ll need a language server for C# and a way to generate `.csproj` files. Unfortunately, it’s difficult to test if the former is working without having the latter up and running. Let’s set up project file generation first.
Due to some weirdness (read: obtuseness) from Unity, you need to fool it into thinking it’s launching JetBrains Rider in order to get it to generate project files when you open a script in an external editor. Luckily, there’s a handy tool called [rider2emacs](https://github.com/elizagamedev/rider2emacs) that pulls that heist off excellently. I did a pretty bland `cargo install rider2emacs` (make sure you have Cargo and Rust installed with Macports) and followed the instructions on the repo to get that working. Double-clicking on a script in Unity generated the `.csproj` files just fine, so let’s move on to getting the language server running.
Assuming you have LSP Mode installed, a C# server is only an M-x away. Use the `lsp-install-server` command and pass it the `omnisharp` argument to get Omnisharp installed.
Now comes the part that made me tear hair out. Omnisharp requires an implementation of the .NET runtime to work. Most guides suggest Mono, but this just didn’t seem to work for me. Opening a script from Unity got it working in Emacs, but Omnisharp kept complaining that it couldn’t find `libhostfxr.dylib`.
A fatal error occurred. The required library libhostfxr.dylib could not be found.
If this is a self-contained application, that library should exist in [/Users/<user>/.emacs.d/.local/etc/lsp/omnisharp-roslyn/latest/omnisharp-roslyn/].
If this is a framework-dependent application, install the runtime in the global location [/usr/local/share/dotnet] or use the DOTNET_ROOT environment variable to specify the runtime location or register the runtime location in [/etc/dotnet/install_location].
The .NET runtime can be found at:
- https://aka.ms/dotnet-core-applaunch?missing_runtime=true&arch=arm64&rid=osx.11.1-arm64&apphost_version=6.0.0-preview.7.21317.1
Process omnisharp stderr finished
Rats. I followed [a guide from the maintainer of rider2emacs](https://eliza.sh/2021-06-01-using-unity-editor-with-emacs.html), setting the `FrameworkOverridePath` to the path of Mono, as installed by Macports. No dice. I was just about to lose it until I found a hint in Doom Emacs’ documentation on its C# language module:
>This module requires:
>
>Mono (on UNIX platforms) .NET SDKs (on Windows) .NET Core 1.X - 3.X or .NET 5 for cross platform
I’m no expert here, but I figured that Unity makes cross-platform games and apps, so I tried swapping away from Mono. I did `port install dotnet-sdk-6` to install the .NET Core, then, I tried opening a script from Unity. Same error. I did a sanity check and saw that Macports didn’t link the install into the usual `/usr/local/share` location, so I set an environment variable `DOTNET_ROOT` to the location it *did* install, which is tucked away in `/opt/local/share/dotnet/`. I just added this to my Doom `config.el`.
(setenv "DOTNET_ROOT" "/opt/local/share/dotnet")
Opening up a script from Unity works perfectly now! LSP Mode autocompletes swimmingly and it’s all up and running smoothly.
**Edit:** Omnisharp is failing to find the UnityEngine namespace with this configuration. I'm looking into solutions for this.
​
elizadev · 2022-11-16 09:00
Hello, I'm the author of the blog you linked 🙂 Glad you figured out how to get this working on macOS, I might have to link to this post on my blog.
I think part of the problem is actually the version of omnisharp that lsp-mode downloads is just... kind of jank compared to the ones that package managers provide. I can't speak any more for macOS there though unfortunately. I've since switched to eglot and a package manager version of omnisharp since writing thst post and have had a better experience.
the_plonkmaster · 2022-11-16 11:38
I may try out a Mono config with a better version of Omnisharp if I can be bothered to fix what's not broken at some point.
In any case, thank you so much for your work on rider2emacs and your blog! Your work is invaluable and you should be really proud of how useful that little utility is! I almost backed out of learning Unity and went back to Godot because I couldn't see a way to get it into an Emacs workflow 😂
the_plonkmaster · 2022-11-17 02:21
Would you be willing to share your Eglot setup? I've realised that Omnisharp is now failing to recognise anything in the UnityEngine namespaces (not just failing to offer autocompletion but outright saying that the namespace couldn't be found), so I may have to take another approach.
ericdallo · 2022-11-23 23:08
Thanks for this, I used doom-emacs + lsp-mode with unity a year ago, and took some time to setup, especially make omnisharp recognize UnityEngine, I ended up using lsp-mode but not using the server from there, but a manual omnisharp installed.
I intend to go back now to unity again after some time, so if there is anything to improve on lsp-mode side, I'll try to do, LMK if you know anything as well
ericdallo · 2022-11-24 02:19
u/elizadev do you know what version from here should be the correct to use with Unity?
[https://github.com/OmniSharp/omnisharp-roslyn/releases](https://github.com/OmniSharp/omnisharp-roslyn/releases)
AFAICS lsp-mode already uses the latest from there but the \`-net\` ones, are those correct?
ericdallo · 2022-11-25 01:31
FYI u/the_plonkmaster u/elizadev I made a commit on lsp-mode improving the way checks for omnisharp-roslyn, now it follows other lsps like Clojure, checking if there is any omnisharp-roslyn on system first before asking to download.
I use nix package manager and after installing omnisharp-roslyn, dotnet-sdk and mono, lsp-mode starts properly including loading Unity stuff correctly :)
the_plonkmaster · 2022-11-25 01:45
You are a legend. I'm going to try out your solution in a few hours when I have my machine. Weird that the LSP Mode-installed Omnisharp is somehow different from a separate install. It seems to just pull straight from the latest GitHub release.
ericdallo · 2022-11-27 15:24
Yep, it just pull from latest github releases so weird to not work, LMK if there is anything to be improved on there
the_plonkmaster · 2022-12-03 01:01
Tried this out, still not working on macOS. I have Mono, .NET Core SDK, and Omnisharp installed. LSP Mode finds my version of Omnisharp fine, but, just like before with the LSP Mode-installed Omnisharp, I'm still not seeing any Unity namespaces.
ericdallo · 2022-12-03 13:23
What happens if you run \`Omnisharp\` on the project root via terminal? It should not print any errors like Mono or .NET not found.
I suggest you bring this to Emacs-lsp's Discord so we can have a more real time chat
jaimesv · 2022-12-14 05:18
Hi, First of all thank you very much!!!!
I was struggling a lot with the setup, I am new o C# and Unity, and I love doom emacs so I didn't want to switch to other editors or IDE's, it is possible that you have solved the UnityEngine workspace not found issue, but if it helps, what I did to make it work was to follow your instructions and also adding in my init.el file under the lang section
(csharp +lsp +unity)
I have in my config.el this line to install omnisharp
(use-package omnisharp
:ensure t)
Apparently, after doing the doom sync and configuring the external tools in Unity using the latest version of rider2emacs it is working ok and detecting the UnityEngine workspace (and lsp recognize it as well)
​
in the external tools in the External Script Editor i gave it the full path to the rider2emacs $HOME/.cargo/bin/rider2emacs
and I didn't changed the External Script Editor ARgs.
​
After it generates de .csproj file it is working ok, maybe another quick note is that I manually downloaded the omnisharp-roslyn lsp, probably the latest version make it work.
Thank you again for this post, you saved my dreams!!