Unity Netstandard2.1

0 views
Skip to first unread message

Chris

unread,
Aug 4, 2024, 4:36:08 PM8/4/24
to jotigertbrob
Iwant to use some NuGet packages inside Unity. I achieved that Unity finds the downloaded DLLs according to this article ( -could-possibly-go-wrong.com/unity-and-nuget/). The nuget.config file can be configured to download the packages into the Plugins folder inside the Assets folder. The Problem is that NuGet downloads multiple versions of each DLL (eg net46, netcore50, netstandard21, so forth) and Unity doesn't like multiple DLLs with the same name. I know I could simply put the DLL inside the Plugins folder by hand, but unfortunately that is not a solution which would please me.

You really don't wanna go down the path of configuring Unity to work with Nuget automatically. That article is rather old. With Unity 2018, you get a .net standard 2.0 compatibility level, which should be perfect for Nuget packages. Simply download the package using a separate VS project (as mentioned in the article), then take the netstandard20 version of the DLL and place it in your Unity project.


You may want to omit -NoCache it prevents nuget from using the cache at C:\Users\\.nuget\packages. This is useful if you use a private nuget feed and there are already packages in your cache which fits your desired packages names and versions but are from a different feed.


The downside of this approach is that you will have both in ./Assets/Plugins the netstandard2.0-Library and the Nuget package like so:Nuget packages a usually not that big so that should not be a factor.Also note you this approach will not resolve package dependencies, you will have to list them in packages.config yourself.


Edit: I noticed another downside: NugetPackages which target multiple frameworks, will be installed as well. This leads to an Unity-Error and need to delete these framework-installs yourself.


Then Unity threw a bunch of errors in the console, and all of them looked like compatibility issues, so I went back to nuget.org and look at the dependencies of the package. Then I repeated the steps above for each package that unity threw errors for initially.


You have to set up the downloaded nuget /is in packages folder/ plugins manually. Nuget doesn't know which plugin can use unity and how. You can set their parameters in inspector: editor, standalone ... x86,x64 ...


Unity doesn't use MSBuild for compiling their C# projects. Instead, they use a homegrown tool called Bee. Normally, when you want to reference a Nuget package, you go into your .csproj file, and add a PackageReference field pointing to the Nuget package. Unity doesn't expose .csproj files to the developer at all, mostly because they don't support all the cool stuff you can do in a .csproj file, such as adding Nuget references. Instead, Unity offers Assembly Definitions, which are like .csproj files, but different...


An Assembly Definition defines a list of .cs files to be compiled into a single .dll by their compiler framework, Bee. You can'tadd Nuget references to an Assembly Definition, but you can add precompiled .dll references... In the Unity Inspector, when you create an Assembly Definition, you can click on it, and add existing .dll files. Those .dll files get included in your project's final build, and you can reference code in those .dll files from within the .cs files included in the Assembly Definition.


There are a bunch of build targets for Nuget packages, as you listed in your question, like net46, or NetStandard 2.1. A Nuget package can contain prebuild .dll files for many frameworks, which makes them portable to a larger set of consumers. Recent versions of Unity can support NetStandard2.1, which is great. BNuget will automatically extract those NetStandard based .dll files for you out of the package. This means you don't really need to bother with thinking about the various frameworks, but it does mean the Nuget packages you pull in MUST support NetStandard.


Once all required tools are installed, it is time to create a new project.BepInEx plugins require at least one C# file which is annotated with BepInPlugin.In addition, to make plugins code compile, we need to reference BepInEx libraries and game-specific libraries.


Some basic information is needed for BepInEx to know how to load the plugin and to allow plugins to interact.Such information is commonly plugin name, a unique identifier and plugin version.Additionally, plugins might need to specify constraints such as dependencies and game names on which plugin can run.


GUIDs are meant to be unique and permanent for a plugin. As you will see with other metadata attributes, other plugins depend on your GUID to be the same.From a practical point of view, avoid changing your plugin DLL's name as well!


The plugin template from BepInEx.Templates contains a helper tool that automatically generates PluginInfo from information located in the .csproj file.For example, the plugin's version is automatically set from component in the project configuration.

You can use the helper tool or replace it with your own values at any time.


In some cases, you may want to allow to load the plugin only in certain games.For instance, your plugin only works in one game, and you want to prevent users from installing a plugin into the wrong one.Alternatively, there might be multiple games in the same game folder, and you want to load your plugin only in one of those games.


The attribute has only one parameter: ProcessName, which is simply the name of the process that the plugin is allowed to run on (including the .exe extension).

Naturally, you can specify the attribute multiple times.


In certain situations, your plugin might be incompatible with other ones.For example, your plugin might already implement some features that another plugin does.You may also desire to simply not load your plugin if another plugin is present.


In these cases, you can use BepInIncompatibility attribute.

Suppose a plugin mentioned in the attribute is present in the game.In that case, your plugin will be not loaded, and a warning message will be given to the user.


To use and modify the game's code, you need to reference libraries that contain it.By default, the BepInEx plugin template includes some of the libraries you need to create a basic project.Such libraries are BepInEx base libraries (provide BepInEx API) and libraries for hooking and modifying game code (such as HarmonyX and MonoMod).

Plugin template for Mono Unity also includes Unity's base libraries used to interact with the Unity engine itself.


NuGet is an online library repository for .NET projects.

BepInEx has its own NuGet feed which includes some game-specific libraries uploaded by the community.

All packages with GameLibs in the name contain game-specific libraries:


If possible, do not reference the assemblies directly from the game folder!

Doing so might cause referencing issues in some versions of C# compilers.

Instead, create a lib folder inside your plugin project and copy any game assemblies to there that you want to reference.


This is by far the largest section of the tutorial. Here, we created our project, looked through BepInEx metadata, added game assemblies, built and tested our plugin.

You can now continue by adding code to the plugin.

Inspect how the game works, experiment and test!


The next sections are related primarily to helper features BepInEx provides.You do not have to know of them to make a plugin, but making use of BepInEx helpers can make common boilerplate more manageable.

Remember that you can always reference BepInEx API Docs to see all available BepInEx methods.


Unity only recognizes DLLs placed under the Assets folder, so we need a way to get the DLLs into the Assets folder. We cannot add the Nuget packages to the project files as we would for other .NET projects because Unity generates the sln and project files. This means that any NuGet packages that we have installed using the IDE will get wiped out by Unity.


Copy the DLL from the netstandard2.1 folder into the Assets/Plugin/DI folder. Remember how Unity needs DLLs to be inside the Assets folder. I prefer to put the DLL into nested folders under Assets, so it's easier to manage multiple DLLs.


Copy the DLL from packages\Microsoft.Extensions.DependencyInjection.Abstractions.6.0.0\lib\netstandard2.1 to the Assets/Plugin/DI folder. It is because Unity needs the Microsoft.Extensions.DependencyInjection.Abstractions.dll.


This is the first post in a new series on upgrading from ASP.NET Core 2.x to ASP.NET Core 3.0. I'm not going to cover big topics like adding Blazor or gRPC to your apps. Instead I'm going to cover the little confusing things like how to upgrade your libraries to target ASP.NET Core 3.0, switching to use the new generic-host-based server, and using endpoint routing.


If you're starting on an upgrade from ASP.NET Core 2.x to 3.0, I strongly suggest following through the migration guide, reading my series on exploring ASP.NET Core 3.0, and checking out Rick Strahl's post on converting an app to ASP.NET Core 3.0. A recent ASP.NET community standup also walked though the bare minimum for upgrading to 3.0. That should give you a good idea of issues you're likely to run into.


For the purposes of this post, I'll assume you have one or more class libraries that you're in control of, and are trying to decide how to support .NET Core 3.0. I consider the following cases, separated based on your library's dependencies:


The first question you have to answer is whether you even need to update your library. Unfortunately, there isn't a simple answer to this question due to some of the changes that came with .NET Core 3.0.


Specifically, .NET Core 3.0 introduces the concept of a FrameworkReference. This is similar to the Microsoft.AspNetCore.App metapackage in ASP.NET Core 2.x apps, but instead of being a NuGet package that references other NuGet packages, the framework is installed along with the .NET Core runtime.


This has implications when your class library references packages that used to exist as NuGet packages, but are now pre-installed as part of the shared framework. I'll try to work through the various combinations of target frameworks and NuGet references your library has, to give you an idea of your options around upgrading your library to work with .NET Core 3.0.

3a8082e126
Reply all
Reply to author
Forward
0 new messages