mardi 2 août 2016

Compiling assemblies for Unity3D using Xamarin 6.x on OSX

8th June 2016, Xamarin releases Xamarin Studio 6.0.0 on OSX, replacing it by Visual Studio 2015 on Windows systems. This version comes with Mono 4.4.x by default, which doesn't support dotNET Framework 3.5. Problem, it's the only way to create compatible assemblies for Unity3D on OSX.

Unity3D, Mono and .NET Framework 3.5

Mono 2.6.5, estimated release between April and July 2010. As I write this article, it's been six years since Unity Technologies integrated Mono into Unity3D. This version doesn't even appear on Mono releases page, and it has been patched by Unity3D to fix some known bugs. Six years means a century, specially to Mono, that introduced loads of improvements since 2010.
Anyway, a good point with Mono is to be able to compile C# assemblies and run them cross platform. Mono 2.6.5 supports dotNET Framework 3.5. To be precise, it's more a custom version of dotNET 2.0 with upgraded features. In the end, compiling assemblies targeting dotNET Framework 3.5 makes them compatible with your Unity3D project.
If you want to create a dotNET library using your MacBook, you'd probably use Xamarin Studio. Before Xamarin 6.x, you could install Xamarin on Windows, OSX and Linux. But since Microsoft bought Xamarin, they replaced it on Windows systems by Visual Studio, that now includes Xamarin features.

Compiling for Unity3D

Mono 4.x

Introducing Mono 4.x, it was decided to get rid of obsolete versions of dotNET Framework. It came with big improvements, and was a first step rapprochement between Xamarin and Microsoft, because it merged some open source code from Microsoft code base. But dotNET 3.5 was dropped, so it's not possible to compile assemblies for Unity3D with Mono anymore. The last Unity3D compliant version of Mono is 3.12.1, released in March 2015, available here.

Using Mono 3.12.1 in Xamarin 5.x

By downloading from the archives, you'll be able to add it to the dotNET runtime and set it as default runtime. You then could create or open projects targeting dotNET Framework 3.5

The problem with Xamarin 6

I first was pretty excited using this new version of Xamarin. A major version of a software we use on a daily basis is always a big event. And this version came with some great features I couldn't wait to try. So I decided to let Xamarin 5.X remove itself and let its successor take the place.
Because I wanted to keep working on my Unity3D libraries, I opened my workspace full of dotNET 3.5 targeted solutions. Then some weird things happened. Impossible to make a clean build, or even build, and my source code seemed to not to know anything about C#.

In the end, disabling MSBuild made the trick

I tried a lot of things, even create a clean new project using Mono 3.12.1. I also sent a bug on Xamarin bug tracking system. Then I switched back to Xamarin 5 because, in the end, it was good enough to do the job.
But as Xamarin 6.0.1, then 6.0.2 have been released, the problem remained, so I decided to try one more time, and eventually succeeded in making it work. The only thing I did was to uncheck Use MSBuild build engine, in Build/General section of my project properties panel.
I didn't take time to figure out what I don't get by not using MSBuild, but I now can keep working on my source code and support Xamarin next updates.

Good hope from DotNet Core

For sure, upgrade Mono in Unity3D seems to be a big journey, but even if Mono is free to use, embedding it in a commercial software like Unity3D takes a commercial license, probably expensive enough to demotivate the Unity Technologies team. That's what I think. I wish I could know the real reasons.
Anyway, these last months Microsoft made big efforts to come closer to the open source community as well as Linux community. On June 27, 2016, Microsoft announced dotNET Core 1.0, available on Windows, OSX and Linux. This version seems to be open enough to make it the great candidate for the best update Unity3D could have.
There was a time when I started thinking of getting rid of C#. I really like this language but having Microsoft dotNET in the Windows platform, and "just" Mono on the other platforms, was a bit unconfortable. Not that easy to bet on a tech when its "real" version is not available on every platform, like C++, NodeJS or Python. I always had the same opinion about DirectX vs OpenGL (now DirectX 12 vs Vulkan)
Having a single, unified, cross-platform technology is easier to consider in long term, particularly if a big player like Microsoft maintains it.

2 commentaires:

  1. Thanks for the info. I have stumbled on the same issue. The first time I built my library it worked with the MSBuild engine. I simply replaced the missing references with the ones from the folder. Trying my luck I removed the reference to System.Core which didn't seem to be needed. I recompiled and then Unity crashed on start. From then on, I wasn't able to recover my project even with the old mono version. I am working on fixing my problem. Your solution seems to work with a clean project, but in my case it crashed the second time I opened my project imported from 5.3.5 after rebuilding my assemblies.

  2. I found the issue. Unity will crash on start when it detects new assemblies to load. Importing assemblies to an Unity project works fine when it is running. Otherwise it crashes for me.