Unity Package Manager

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

Unity Package Manager

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 - β€œby hand” we duplicate resources between projects.

Pros:

  • Suitable for all kinds of resources.
  • No dependency issues.
  • No problem with asset GUIDs.

Cons:

  • Giant repositories.
  • There is no option for versioning.
  • Difficulty tracking changes to shared resources.
  • Difficulty updating shared resources.

2. Git submodules - distribution of shared resources through external submodules.

Pros:

  • You can work with sources.
  • You can distribute assets.
  • No dependency issues.

Cons:

  • Git skills required.
  • Git is not very friendly with binary files - you have to include LFS.
  • Access control for repositories.
  • Difficulty upgrading and downgrading.
  • GUID collisions 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 do not depend on Unity.
  • Convenient versioning and dependency resolution.

Cons:

  • Unity does not know how to work with NuGet packages out of the box (you can find NuGet Package Manager for Unity on GitHub, which fixes this, but there are 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.
  • Versioning capability.
  • Ability to distribute all kinds of resources for Unity.

Cons:

  • GUID conflicts can still happen.
  • There is no documentation for the implementation.

The latter method has more advantages than disadvantages. However, it is not very popular now due to the lack of documentation, and therefore we will dwell on it in detail.

Unity Package Manager

Unity Package Manager (hereinafter referred to as UPM) is a package management tool. It was added in Unity 2018.1 and was only used for packages developed by Unity Technologies. However, starting with version 2018.3, it became possible to add custom packages.

Unity Package Manager
Unity Package Manager Interface

Packages do not end up in the project sources (Assets directory). They are in a separate directory. %projectFolder%/Library/PackageCache and do not affect the project in any way, their only mention in the source code is in the file packages/manifest.json.

Unity Package Manager
Packages in the project file system

Package sources

UPM can use several package sources:

1. File system.

Pros:

  • Implementation speed.
  • Requires no third party tools.

Cons:

  • versioning complexity.
  • Shared access to the file system is required for everyone who works with the project.

2. Git repository.

Pros:

  • All you need is a Git repository.

Cons:

  • You cannot switch between versions through the UPM window.
  • Doesn't work with all Git repositories.

3. npm repository.

Pros:

  • Fully supports UPM functionality and is used to distribute official Unity packages.

Cons:

  • Currently ignores all string versions of packages except "-preview".

We'll look at the UPM + npm implementation below. 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.

As an npm repository, you can use Verdaccio. It has a detailed documentation, and it takes literally a couple of commands to run it.

Environment setup

First you need to install node.js.

Create a package

To create a package, you need to put the file package.json, which will describe it, to 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 npm init command and enter the required values ​​during the dialog. For name, specify the name in reverse domain format, for example, com.plarium.somepackage.
For convenient display of the package name, add the displayName property to package.json and fill it in.

Since npm is js-oriented, the file contains the main and scripts properties that we do not need, which Unity does not use. It is better to remove them so as not to clog up the description of the package. The file should look something like this:

  1. Go to the project directory that we want to make a package.
  2. Run the npm init command and enter the required values ​​during the dialog. For name, specify the name in reverse domain format, for example, com.plarium.somepackage.
  3. For convenient display of the package name, add the displayName property to package.json and fill it in.
  4. Since npm is js-oriented, the file contains the main and scripts properties that we do not need, which Unity does not use. It is better to remove them so as not to clog up the description of the package. 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"
    }

  5. Open Unity and generate a .meta file for package.json (Unity doesn't see assets without .meta files, Unity packages open read-only).

Sending a package

To send a package, you need to run the command: npm publish --registry *адрСс Π΄ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²*.

Installing and updating packages through the Unity Package Manager

To add a package to a Unity project, you need to:

  1. Write to file manifest.json information about the source of the packages. To do this, you need to add a property scopedRegistries and indicate the scopes and the address of the source by which specific scopes will be searched.
    
    "scopedRegistries": [
       {
         "name": "Main",
         "url": "адрСс Π΄ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²",
         "scopes": [
           "com.plarium"
         ]
       }
     ]
    
  2. Go to Unity and open the Package Manager window (working with custom packages is no different from working with built-in ones).
  3. Select All Packages.
  4. Find the required package and add it.

Unity Package Manager

Working with sources and debugging

In order for the sources to be connected to the project, you need to create Assembly Definition for the package.

The use of packages does not limit the scope for debugging. 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 because Unity does not see the scripts as separate files, because when using the Assembly Definition, they are collected into a library and included in the project. When working with sources from a project, a click-through transition to the IDE is available.

Script in a project with a connected package:

Unity Package Manager
Script from the package with a working breakpoint:

Unity Package Manager

Urgent fixes to packages

Unity packages added to the project are read-only, but can be edited in the package cache. For this you need:

  1. Go to the package in the package cache.

    Unity Package Manager

  2. Make the necessary changes.
  3. Update version in file package.json.
  4. send package npm publish --registry *адрСс Π΄ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²*.
  5. Update the package version to the corrected version through the UPM interface.

Package import conflicts

When importing packages, the following GUID conflicts may occur:

  1. Package - package. If, when importing a package, it is found that already added packages contain assets with the same GUID, assets with matching GUIDs from the imported package will not be added to the project.
  2. Package is a project. If, when importing a package, it is found that the project has assets with matching GUIDs, then the assets from the package will not be added to the project. However, the assets that depend on them will start using the assets from the project.

Transferring assets from a project to a package

If you transfer an asset from a project to a package while Unity is open, then its functionality will be preserved, and links in dependent assets will start using the asset from the package.

It's important: When copying an asset from a project to a package, the Package-Project conflict described in the section above will occur.

Possible solutions to conflicts

  1. Reassigning GUIDs according to own algorithms when importing all assets to avoid collisions.
  2. Adding all assets to one project with their subsequent separation into packages.
  3. Create a database containing the GUIDs of all assets and validate when submitting packages.

Conclusion

UPM is a new solution for distributing shared resources in 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.

Source: habr.com

Add a comment