nurupo.io
532 words
3 minutes
The Real Way to Install NuGet in Unity

The NuGet Installation Challenge#

I’ve been working on a Unity project that requires external libraries. After multiple attempts with NuGet for Unity (https://github.com/GlitchEnzo/NuGetForUnity), which worked inconsistently, I created a PowerShell script for a more reliable method of installing NuGet packages in Unity projects.

asieradzk
/
RL_Matrix
Waiting for api.github.com...
00K
0K
0K
Waiting...

I’ve mainly needed it to use and develop my magnum opus - RLMatrix. A pure C# replacement for Unity’s ml-agents or deep reinforcement learning libs like stable-baselines. My library has a lot of dependencies and I needed a robust way to install and uninstall them.

The PowerShell Script#

Here’s the script that makes it all happen:

$packageName = "RLMatrix"
$packageVersion = "0.4.0"
$netTarget = "netstandard2.0"
$tempDir = ".\Temp"
$dllDir = ".\Assets\Plugins"
$nugetPath = "C:\nuget.exe"

if (!(Test-Path $nugetPath)) {
    Write-Error "NuGet.exe not found at $nugetPath. Please ensure it's installed there or update the path."
    exit 1
}

if (!(Test-Path $tempDir)) {
    New-Item -ItemType "directory" -Path $tempDir
}

& $nugetPath install $packageName -Version $packageVersion -OutputDirectory $tempDir

if (!(Test-Path $dllDir)) {
    New-Item -ItemType "directory" -Path $dllDir
}

Get-ChildItem -Path $tempDir -Directory | ForEach-Object {
    $packagePath = Join-Path $_.FullName "lib\$netTarget"
    if (Test-Path $packagePath) {
        Get-ChildItem -Path $packagePath -Filter "*.dll" | ForEach-Object {
            $destinationPath = Join-Path $dllDir $_.Name
            if (!(Test-Path $destinationPath)) {
                Copy-Item -Path $_.FullName -Destination $destinationPath
            }
        }
    }
}

Remove-Item $tempDir -Recurse -Force

How to Use the Script#

You can download nuget CLI from here: https://learn.microsoft.com/en-us/nuget/install-nuget-client-tools?tabs=windows Alternatively its possible to add this to PATH but its not my preferred way.

  1. Save this script in your Unity project directory where you want your dependencies.
  2. Change $packageName and $packageVersion to match your desired package.
  3. Ensure $nugetPath points to your nuget.exe location.
  4. Right-click the script in Windows Explorer and select “Run with PowerShell”.
NOTE

Always use the exact version number from nuget.org for $packageVersion. Don’t guess or use an approximate version.

How the Script Works#

Let’s break down the key parts of the script:

  1. Setup and Checks:
$packageName = "RLMatrix"
$packageVersion = "0.4.0"
$netTarget = "netstandard2.0"
$tempDir = ".\Temp"
$dllDir = ".\Assets\Plugins"
$nugetPath = "C:\nuget.exe"

if (!(Test-Path $nugetPath)) {
    Write-Error "NuGet.exe not found at $nugetPath. Please ensure it's installed there or update the path."
    exit 1
}

This section sets up the necessary variables and checks if nuget.exe exists at the specified path.

  1. Package Installation:
if (!(Test-Path $tempDir)) {
    New-Item -ItemType "directory" -Path $tempDir
}

& $nugetPath install $packageName -Version $packageVersion -OutputDirectory $tempDir

Here, we create a temporary directory and use nuget.exe to install the specified package and its dependencies.

  1. DLL Extraction:
if (!(Test-Path $dllDir)) {
    New-Item -ItemType "directory" -Path $dllDir
}

Get-ChildItem -Path $tempDir -Directory | ForEach-Object {
    $packagePath = Join-Path $_.FullName "lib\$netTarget"
    if (Test-Path $packagePath) {
        Get-ChildItem -Path $packagePath -Filter "*.dll" | ForEach-Object {
            $destinationPath = Join-Path $dllDir $_.Name
            if (!(Test-Path $destinationPath)) {
                Copy-Item -Path $_.FullName -Destination $destinationPath
            }
        }
    }
}

This section creates a directory for the DLLs and then recursively searches for and copies all relevant DLL files from the installed package and its dependencies.

  1. Cleanup:
Remove-Item $tempDir -Recurse -Force

Finally, we remove the temporary directory to clean up after the installation.

It’s almost comical how such a simple script can solve what seems to be a common problem. You’d think Unity would have built-in support for this by now. But hey, maybe when Unity finally upgrades from Mono to .NET Core in the next 2-10 years, we won’t need workarounds like this anymore. Until then, happy NuGetting!

The Real Way to Install NuGet in Unity
https://nurupo.io/posts/unityhowtonuget/
Author
Adrian Sieradzki
Published at
2024-08-08