
Unity Package Manager
- Tutorial
Unity is a platform that has existed for a long time and is constantly evolving. However, working in it with several projects at the same time, you can still encounter difficulties in using common sources (.cs), libraries (.dll) and other assets (images, sounds, models, prefabs). In this article, we will talk about our experience working with a native solution to such a problem for Unity.

There is more than one way to use shared resources for different projects, but each approach has its pros and cons.
1. Duplication - “hands” duplicate resources between projects.
Pros:
Minuses:
2. Git submodules - distribution of shared resources through external submodules.
Pros:
Minuses:
3. NuGet - distribution of shared libraries through NuGet packages.
Pros:
Minuses:
4. Unity Package Manager - distribution of shared resources through a native solution for Unity.
Pros:
Minuses:
The latter method has more advantages than disadvantages. However, it is not very popular right now due to the lack of documentation, and therefore we will dwell on it in detail.
Unity Package Manager (hereinafter UPM) is a package management tool. It was added in Unity 2018.1, and it was used only for packages developed by Unity Technologies. However, starting with version 2018.3, it became possible to add custom packages.

Unity Package Manager interface
Packages do not get into the project sources (Assets directory). They are located in a separate directory

Packages in the project file system
UPM can use several sources of packages:
1. File system.
Pros:
Minuses:
2. Git repository.
Pros:
Minuses:
3. npm repository.
Pros:
Minuses:
Below we look at the implementation of UPM + npm. This bundle is convenient because it allows you to work with any kind of resources and manage package versions, and also fully supports the native UPM interface.
You can use Verdaccio as an npm repository . There is detailed documentation for it, and it will take just a couple of commands to launch it.
First you need to install node.js .
To create a package, you must place the file
To send you must run the package:
To add a package to a Unity project, you need:

In order for the sources to connect to the project, you must create an Assembly Definition for the package.
Using packages does not limit debugging capabilities. However, when working with packages in Unity, you cannot go to the IDE by clicking on an error in the console if the error occurred in the package. This is due to the fact that Unity does not see scripts as separate files, because when using Assembly Definition they are collected in a library and connected to the project. When working with source codes from a project, switching to the IDE by click is available.
The script in the project with the package connected:

Script from the package with a working breakpoint:

Unity packages added to the project are read-only, but they can be edited in the package cache. To do this, you must:
When importing packages, the following GUID conflicts can occur:
If you transfer assets from a project to a package with Unity open, its functionality will be preserved, and links in dependent assets will start using assets from the package.
Important : when you copy an asset from a project to a package, the conflict "Package - Project" will occur, as described in the section above.
UPM is a new solution for distributing shared resources to Unity, which can be a worthy alternative to existing methods. The recommendations described in the article arose on the basis of real cases. We hope you find them useful.

Shared Resource Distribution Methods
There is more than one way to use shared resources for different projects, but each approach has its pros and cons.
1. Duplication - “hands” duplicate resources between projects.
Pros:
- Suitable for all kinds of resources.
- No dependency issues.
- No problem with asset GUIDs.
Minuses:
- Gigantic repositories.
- No versioning possible.
- The difficulty of tracking changes to shared resources.
- Difficulty updating shared resources.
2. Git submodules - distribution of shared resources through external submodules.
Pros:
- You can work with source codes.
- Assets can be distributed.
- No dependency issues.
Minuses:
- Git skills needed.
- Git is not very friendly with binary files - you have to connect LFS.
- Access control for repositories.
- Difficulties in upgrading and downgrading.
- Collisions of GUIDs are possible and there is no unambiguous behavior on the part of Unity to resolve them.
3. NuGet - distribution of shared libraries through NuGet packages.
Pros:
- Convenient work with projects that are not dependent on Unity.
- Convenient versioning and resolution of dependencies.
Minuses:
- Unity does not know how to work with NuGet packages out of the box (on GitHub you can find NuGet Package Manager for Unity, which fixes this, but there are some nuances).
- Difficulties in distributing other types of assets.
4. Unity Package Manager - distribution of shared resources through a native solution for Unity.
Pros:
- Native interface for working with packages.
- Protection against overwriting .meta files in packages in case of GUID conflicts.
- Possibility of versioning.
- The ability to distribute all kinds of resources for Unity.
Minuses:
- GUID conflicts may still occur.
- There is no documentation to implement.
The latter method has more advantages than disadvantages. However, it is not very popular right now due to the lack of documentation, and therefore we will dwell on it in detail.
Unity Package Manager
Unity Package Manager (hereinafter UPM) is a package management tool. It was added in Unity 2018.1, and it was used only for packages developed by Unity Technologies. However, starting with version 2018.3, it became possible to add custom packages.

Unity Package Manager interface
Packages do not get into the project sources (Assets directory). They are located in a separate directory
%projectFolder%/Library/PackageCache
and do not affect the project in any way; their only mention in the sources is in the file packages/manifest.json
.
Packages in the project file system
Package Sources
UPM can use several sources of packages:
1. File system.
Pros:
- Speed of implementation.
- No third-party tools required.
Minuses:
- The complexity of versioning.
- File sharing is required for everyone who works with the project.
2. Git repository.
Pros:
- Only a Git repository is needed.
Minuses:
- You cannot switch between versions through the UPM window.
- It doesn’t work with all Git repositories.
3. npm repository.
Pros:
- Fully supports UPM functionality and is used to distribute official Unity packages.
Minuses:
- Currently, it ignores all string versions of packages except for "-preview".
Below we look at the implementation of UPM + npm. This bundle is convenient because it allows you to work with any kind of resources and manage package versions, and also fully supports the native UPM interface.
You can use Verdaccio as an npm repository . There is detailed documentation for it, and it will take just a couple of commands to launch it.
Environment setting
First you need to install node.js .
Package creation
To create a package, you must place the file
package.json
that will describe it in the directory with the contents of this package. You need to do the following:- Go to the project directory that we want to make a package.
- Run the command
npm init
and enter the necessary values during the dialog. For name, specify the name in the format of the reverse domain, for examplecom.plarium.somepackage
. - To conveniently display the package name, add the property
displayName
topackage.json
and fill it. - Since npm is js-oriented, the file contains properties that we do not need
main
andscripts
that Unity does not use. It is better to remove them so as not to clutter up the package description. The file should look something like this:{ "name": "com.plarium.somepackage", "displayName": "Some Package", "version": "1.0.0", "description": "Some Package Description", "keywords": [ "Unity", "UPM" ], "author": "AUTHOR", "license": "UNLICENSED" }
- Open Unity and generate a .meta file for package.json (Unity does not see assets without .meta files, packages for Unity open only for reading).
Package sending
To send you must run the package:
npm publish --registry *адрес до хранилища пакетов*
.Installing and updating packages through Unity Package Manager
To add a package to a Unity project, you need:
- Enter
manifest.json
information about the source of packages in the file . To do this, you need to add a propertyscopedRegistries
and specify the scopes and the source address by which specific scopes will be searched."scopedRegistries": [ { "name": "Main", "url": "адрес до хранилища пакетов", "scopes": [ "com.plarium" ] } ]
- Go to Unity and open the Package Manager window (working with custom packages is no different from working with built-in packages).
- Select All Packages.
- Find the package you need and add it.

Work with sources and debugging
In order for the sources to connect to the project, you must create an Assembly Definition for the package.
Using packages does not limit debugging capabilities. However, when working with packages in Unity, you cannot go to the IDE by clicking on an error in the console if the error occurred in the package. This is due to the fact that Unity does not see scripts as separate files, because when using Assembly Definition they are collected in a library and connected to the project. When working with source codes from a project, switching to the IDE by click is available.
The script in the project with the package connected:

Script from the package with a working breakpoint:

Urgent patch fixes
Unity packages added to the project are read-only, but they can be edited in the package cache. To do this, you must:
- Go to the package in the package cache.
- Make the necessary changes.
- Update the version in the file
package.json
. - Send the package
npm publish --registry *адрес до хранилища пакетов*
. - Update the package version to the corrected one through the UPM interface.
Package Import Conflicts
When importing packages, the following GUID conflicts can occur:
- Package - package. If, when importing a package, it appears that already added packages have assets with the same GUID, assets with matching GUIDs from the imported package will not be added to the project.
- A package is a project. If, when importing a package, it appears that the project has assets with matching GUIDs, then the assets from the package will not be added to the project. However, assets that depend on them will start using assets from the project.
Transferring assets from a project to a package
If you transfer assets from a project to a package with Unity open, its functionality will be preserved, and links in dependent assets will start using assets from the package.
Important : when you copy an asset from a project to a package, the conflict "Package - Project" will occur, as described in the section above.
Possible conflict solutions
- Reassignment of GUIDs according to their own algorithms when importing all assets to avoid collisions.
- Adding all assets to one project with their subsequent division into packages.
- Creation of a database containing GUIDs of all assets, and validation when sending packets.
Conclusion
UPM is a new solution for distributing shared resources to Unity, which can be a worthy alternative to existing methods. The recommendations described in the article arose on the basis of real cases. We hope you find them useful.