0

I am currently building an external assembly for my Unity projects. For that i have created a new class library project in Visual Studio (Community 2019).

When using specific "System.[...]" resources (e.g. System.Random) i get a TypeLoadException when using the self created dll in my Unity Project.

TypeLoadException: Could not resolve type with token 01000010 (from typeref, class/assembly System.Random, System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)

The Unity version that i used for testing are 2021.1.14f1 and 2022.1.0b8.

I tried switching the framework version of the class library from .NET 5.0 even down to .NET Core 1.0 or also in Unity switching from IL2CPP to Mono or changing the Api Compatibility Level up and down.

Currently none of this has worked for me and somehow i dont find anything that is helping me online.

How can i get on the same framework level in my external visual studio project as the Unity projects that should use the dll?

Thanks a lot in advance!

Jules
  • 1
  • 9
  • For pre-compiled .NET assemblies to use as plugins in Unity be sure your external project is either a .NET Standard 2 class library or .NET Framework 4.x class library. This happens to be the same profiles for code compiled by Unity. https://docs.unity3d.com/Manual/dotnetProfileSupport.html. Note anything beyond .NET Standard 2 including .NET 5 & 6 are not supported in Unity or out –  Feb 22 '22 at 12:08
  • Also I think your attempt of .NET Core 1.0 was just a bit too low. Try again with .NET Standard 2.0 –  Feb 22 '22 at 12:11
  • 1
    Yes this worked for me. I could even use .NET Core 3.1. Thank you! – Jules Feb 22 '22 at 16:08
  • No worries. Check out my update below, I did some more experimentation recently and discovered some things that may prove useful. –  Feb 27 '22 at 06:05

1 Answers1

1

This is a summary of my comments beneath the question.


For pre-compiled .NET assemblies to use as plugins in Unity be sure your external project is either a .NET Standard 2 class library or .NET Framework 4.x class library. This happens to be the same profiles for code compiled by Unity. https://docs.unity3d.com/Manual/dotnetProfileSupport.html.

Note anything beyond .NET Standard 2 including .NET 5 & 6 are not supported in Unity or out.

Also I think your attempt of .NET Core 1.0 was just a bit too low. Try again with .NET Standard 2.0.

Beyond the limits

Beyond .NET Standard 2.0 (inc .NET Core 2.0) with Unity

OP:

Yes this worked for me. I could even use .NET Core 3.1.

Careful though because .NET Core 3.1 (with the TFM1 of netcoreapp3.1) surpasses the last .NET Core-.NET-Standard-compliant build. i.e. .NET Core 3.0 under the .NET Standard 2.1 umbrella which wasn't supported anyway under Unity's Stable scripting runtime (with the max being .NET Standard 2.0).

I tried some experiments of my own and though the plugin was initially loaded by Unity, later I encountered a Unity error stating:

Unloading broken assembly Assets\Plugins\MyExperimental.dll, this assembly can cause crashes in the runtime

Change the C# language version

We can have some early Christmas Presents by changing the C# Language level for the external C# projects that will appear in Unity as pre-compiled assemblies.

The default C# Langage version for a .NET Standard 2.0 project is C# 7.3 whilst .NET Core 3.x project is C# 8.0.

Now in the flight simulator I'm creating, I'd like to represent units of measurement like airspeed, altitude and distance using immutable structs and I'm quite lazy so I don't want to do alot of typing. By staggering coincidence C# 10 has introduced record structs which can be marked as readonly offering true immutability (unlike C# 9). Unforunately .NET Standard 2.0 projects defaults to C# 7.3 so we can't use these features. Luckily there is a way to override the C# language for a project whilst keeping the overall project type the same.

To get C# 10 support open your project file which will look something like the following. Generally you won't find a <LangVersion> specified and so the usual C# version will be in this case C# 7.3 for a .NET Standard 2.0 project as mentioned.

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
        <ImplicitUsings>false</ImplicitUsings>
    </PropertyGroup>
.
.
.
</Project>

Let's change it to C# 10 by adding a <LangVersion> like so:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
        <LangVersion>10.0</LangVersion>
        <ImplicitUsings>false</ImplicitUsings>
    </PropertyGroup>
.
.
.
</Project>

Now when you compile it and drop the resulting assemblies into your Assets\Plugins folder, Unity won't know the difference. The code will be compatible with all your scripts.

Conclusion

Changing the C# language version is a reasonable way to get more language features when a hard border is in place for the max .NET target framework.


1 Target Framework Moniker (TFM), see Target frameworks in SDK-style projects for more information.