Package Manger in C#

How to work with Unity's Package Manager in editor scripts

Like what your seeing?

Support us as a GitHub Sponsor and get instant access to all our assets, exclusive tools and assets, escalated support and issue tracking and our gratitude. These articles are made possible by our GitHub Sponsors ... become a sponsor today!

Introduction

Package Manager, while its not great it is what Unity Technology has moved to and it does give us what we need in terms of a means to query and see what is installed and detect the version that is installed.

How?

using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;

These two namespaces give us everything we need to query what packages are installed and even kick off remove, update or installs operations.

Package Manager processes are asynchronous so you will need a means to handle that. You can use background workers or other methods but we tend to prefer Coroutines as they are familiar to other Unity developers and also let us work with things that aren't thread safe.

Want to know how to use Editor Coroutines? read this article!

Listing Packages

var listProc = Client.List();

while (!listProc.IsCompleted)
    yield return null;

The above code will use the PackageManager.Client to list all installed packages for you. Once the process is completed you should check for success and if so iterate over the results to find what your looking for.

bool isInstalled = false;
if (listProc.Status == StatusCode.Success)
{
    var systemCore = listProc.Result.FirstOrDefault(p => p.name == "com.heathen.systemcore");
    if(systemCore != default)
    {
        isInstalled = true;
        Debug.Log("System Core Version: " + systemCore.version + " is installed");
    }
}
else
    Debug.LogError("Failed to list Package Manager packages: " + listProc.Error.message);

The above example is a crude, non-practical example. Above we are simply searching for an installed package whose name matches System Core's package then setting a bool to true if its there and debug logging its version string.

In reality you would want to for example compare the version with a minimal require version, or perhaps you only care if its not installed so really a

if(!listProc.Result.Any(p => p.name == "com.heathen.systemcore"))
{
    //We need to install it
}

would be more practice for you

Installing/Updating Packages

Installing or updating packages will cause the Unity editor to recompile and thus reload scripts, thus triggering any processes to fire again โ€ฆ you need to uses SessionState parameters that can survive this to manage state.

var sysProc = Client.Add("https://github.com/heathen-engineering/SystemCore.git?path=/com.heathen.systemcore");

The above example uses the PackageManager.Client to add Heathen's System Core tot he manifest. As with listing this is Asynchronous so you need to handle that for example:

while (sysProc.Status == StatusCode.InProgress)
    yield return null;

This would simply yield until complete, this is an example only you could have timeout timers running or similar but it illustrates the point of waiting for that async process to complete.

Finally check for errors and handle them accordingly

if (sysProc.Status == StatusCode.Failure)
    Debug.LogError("PackageManager's System Core install failed, Error Message: " + sysProc.Error.message);
else if (sysProc.Status == StatusCode.Success)
    Debug.Log("System Core " + sysProc.Result.version + " installation complete");

The above code will print the error if any, if none it will print the version that was installed.

Removing Packages

Last updated